Сценарий:
Я создал SCTP-сокет «один ко многим» (функции, которые начинаются с большой буквы, вызывают соответствующие стандартные функции с проверкой на наличие ошибок и выводом errno в stderr)
int sock_fd,msg_flags;
char readbuf[BUFFSIZE];
struct sockaddr_in servaddr, cliaddr;
struct sctp_sndrcvinfo sri;
struct sctp_event_subscribe evnts;
int stream_increment=1;
socklen_t len;
size_t rd_sz;
sock_fd = Socket( AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
bzero( &servaddr, sizeof( servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl( INADDR_ANY);
servaddr.sin_port = htons( SERV_PORT);
Bind( sock_fd, ( SA *) &servaddr, sizeof(servaddr));
bzero( &evnts, sizeof( evnts));
evnts.sctp_data_io_event = 1;
Setsockopt( sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof( evnts));
Listen( sock_fd, LISTENQ);
Затем я блокирую вызов sctp_recvmsg, чтобы прочитать сообщение, когда оно приходит
rd_sz = Sctp_recvmsg( sock_fd, readbuf, sizeof( readbuf),
(SA *)&cliaddr, &len, &sri,&msg_flags);
И после подключения клиента я звоню getsockopt получить текущее состояние ассоциаций SCTP
len = sizeof(struct sockaddr_in);
socklen_t retsz;
struct sctp_status status;
retsz = sizeof(status);
bzero(&status,sizeof(status));
status.sstat_assoc_id = sctp_address_to_associd(sock_fd, (SA *)&cliaddr, len);
getsockopt( sock_fd, IPPROTO_SCTP, SCTP_STATUS, &status, &retsz);
Функция sctp_address_to_associd имеет вид:
sctp_assoc_t
sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t salen)
{
struct sctp_paddrparams sp;
socklen_t siz;
siz = sizeof(struct sctp_paddrparams);
bzero(&sp,siz);
memcpy(&sp.spp_address,sa,salen);
sctp_opt_info(sock_fd,0,
SCTP_PEER_ADDR_PARAMS, &sp, &siz);
return(sp.spp_assoc_id);
}
Почему getsockopt возвращает «Неверный аргумент»? errno = 22. ОС Linux Ubuntu 12.10.
Опция сокета SCTP_PEER_ADDR_PARAMS в sctp_address_to_associd()
Функция не может быть использована для изучения идентификатора ассоциации, по крайней мере, в Linux.
Поскольку вы уже получаете идентификатор ассоциации из вызова sctp_recvmsg (), используйте идентификатор ассоциации struct sctp_sndrcvinfo
вместо:
status.sstat_assoc_id = sri.sinfo_assoc_id;
getsockopt( sock_fd, IPPROTO_SCTP, SCTP_STATUS, &status, &retsz);