天天看點

SCTP應用程式設計中的注意事項

SCTP和TCP、UDP有些不一樣,在寫應用程式的時候需要注意一下。

1. 可以bind多個IP位址

這個是SCTP的特點,兩端都可以用多個IP位址和對端來通信,是以不管是client端,還是server端,都可以bind多個IP位址(端口号必須相同)。

比如:

// bind第一個位址

bind(fd, (struct sockaddr *)&cliaddr1, sizeof(cliaddr));

// bind第二個位址

sctp_bindx(fd, (struct sockaddr *)&cliaddr2, 1, SCTP_BINDX_ADD_ADDR);

cliaddr1和cliaddr2裡面,IP位址不同,PORT相同。

2. 需要注冊事件通知

為了能調用sctp_recvmsg()收到對端發送的DATA,需要事先為該socket注冊一個事件通知功能:

struct sctp_event_subscribe events;

events.sctp_data_io_event = 1;

setsockopt(fd, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events));

不注冊這個事件通知,是不能通過調用sctp_recvmsg()接收對端的DATA的。

類似的,注冊其他事件類型之後,可以通過sctp_recvmsg()收到SCTP_COMM_UP(連接配接建立完成)、SCTP_SHUTDOWN_EVENT(連接配接被關閉)等通知。

events.sctp_association_event = 1;

events.sctp_shutdown_event = 1;

sctp_recvmsg()接口使用方法如下:

 ret = sctp_recvmsg((int) fd,

                      (void *)buf,

                      (size_t)MAX_BUFF_SIZE,

                      (struct sockaddr *)from,

                      &fromlen,

                      (struct sctp_sndrcvinfo *)&rcvinfo,

                      (int *)&l_msg_flags);

通過l_msg_flags就能知道收到的buf中,到底是NOTIFICATION還是DATA(對端應用層的一條消息),以及DATA有沒有接收完整:

 if (l_msg_flags & MSG_NOTIFICATION) { //收到一條通知消息

  l_notif = (union sctp_notification *)buf;

  if (l_notif->sn_header.sn_type == SCTP_ASSOC_CHANGE) {

   l_asschg = &l_notif->sn_assoc_change;

   switch (l_asschg->sac_state) {

   case SCTP_COMM_UP:

   ...

   }

  } else if (l_notif->sn_header.sn_type == SCTP_SHUTDOWN_EVENT) {

   l_shutdown = &l_notif->sn_shutdown_event;

   if (l_shutdown->sse_type == SCTP_SHUTDOWN_EVENT) {

    DEBUG_PRINT(fd, "notification = SCTP_SHUTDOWN_EVENT\n");

    clean_fd(fd);

   }

  }

 } else if (l_msg_flags & MSG_EOR) { //收到一條完整的DATA

  if (!g_data_performance_test) {

   printf("[sctp_recvmsg] fd = %d, %s\n", fd, buf);

  } else {  //收到一條不完整的DATA

   g_message_received++;

   g_message_total_size += ret;

  }

繼續閱讀