2 Replies Latest reply: Mar 25, 2010 10:45 AM by 807567 RSS

    the problem on sctp when using sctp_sendmsg

    807567
      Dear all,

      I tried to create the small program to understand how client and server
      work on SCTP. I created two different kinds of program, one is for 1 to
      1 sctp socket and another is 1 to many socket. The first one, 1 to 1
      socket, is working well but the second one.


      My program for the 1 to many socket is that client send the data to the
      server to establish the connecttion with sctp_sendsmg() and the server
      calls sctp_rcvmsg() to receive the data from the client. This is still
      fine. But the problem is when server want to send data back to client,
      the error is shown. The error message from strerror (errno) is "Address
      already in use".


      Could someone tell me what is wrong with my program?


      #include <stdio.h>
      #include <strings.h>
      #include <iostream.h>
      #include <sys/types.h>
      #include <sys/socket.h>
      #include <netinet/in.h>
      #include <unistd.h>
      #include <errno.h>
      #include <arpa/inet.h>
      #include <netinet/sctp.h>
      #include <sys/uio.h>
      #include <stdlib.h>


      #define BACKLOG 5
      #define SERV_PORT 47123
      #define MAX_MSG 100
      #define MSG_SIZE (MAX_MSG+1)
      #define AUTO_CLOSING_TIME 60
      #define SERV_IP htonl(0x7f000001)


      int main(){


      struct sockaddr_in servaddr, clientaddr;
      int sockfd, confd, msg_flags;
      socklen_t len;
      char str[16];
      char line[MSG_SIZE];
      struct sctp_event_subscribe events;
      struct sctp_sndrcvinfo sockinfo;
      // To creat a 1 to M SCTP socket
      sockfd = ::socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
      if(sockfd < 0){
      char* errmsg = strerror (errno);
      cout << "Creating socket is failed : " << errmsg <<"\n";
      return 0;
      }
      else{
      cout << "Creating socket is successful : " << sockfd <<"\n";
      }


      // To bind a primary IP address to the socket
      bzero(&servaddr, sizeof(servaddr));
      servaddr.sin_family = AF_INET;
      servaddr.sin_addr.s_addr = inet_addr("192.168.139.94");
      servaddr.sin_port = htons (SERV_PORT);
      if(::bind(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr) ) <
      0){
      char* errmsg = strerror (errno);
      cout << "Binding Address to socket is failed : " << errmsg <<"\n";
      return 0;
      }
      else{
      cout << "Binding Address to socket is successful with" << "\n";
      }
      // To bind more IP addresses to the socket
      struct sockaddr_in addrset[2];
      for (int i = 0; i < 2; i++) {
      addrset.sin_family = AF_INET;
      addrset[i].sin_port = htons(SERV_PORT);
      }
      addrset[0].sin_addr.s_addr = inet_addr("192.168.139.93");
      addrset[1].sin_addr.s_addr = SERV_IP;
      if(sctp_bindx(sockfd, (struct sockaddr*) &addrset[0], 2,
      SCTP_BINDX_ADD_ADDR) < 0){
      char* errmsg = strerror (errno);
      cout << "Binding more addresses is failed : " << errmsg <<"\n";
      }
      else{
      cout << "Binding more addresses is successful\n";
      }


      bzero (&events, sizeof (events)) ;
      events.sctp_data_io_event = 1;


      if(::setsockopt(sockfd, IPPROTO_SCTP, SCTP_EVENTS, &events,
      sizeof(events) ) < 0){
      char* errmsg = strerror (errno);
      cout << "Setting data io option is failed : " << errmsg <<"\n";
      return 0;
      }
      else{
      cout << "Setting data io option is successful"<< "\n";
      }


      if(::listen (sockfd, BACKLOG) < 0){
      char* errmsg = strerror (errno);
      cout << "Listenning is failed : " << errmsg <<"\n";
      return 0;
      }
      else{
      cout << "Listenning is successful\n";
      }


      while(true){
      cout << "Waiting for SCTP connection on port " << SERV_PORT << "
      ...\n";


      memset(line, 0x0, MSG_SIZE);
      while (true) {
      int recv_msg_size = sctp_recvmsg(sockfd, line, sizeof(line),
      (struct sockaddr*) &clientaddr, &len, &sockinfo, &msg_flags );
      if(recv_msg_size < 0){
      char* errmsg = strerror (errno);
      cerr << "Error: cannot send data: " << errmsg <<"\n";
      }
      else{
      cout << "---" << line << "----\n";
      cout << "---" << sizeof(line) <<" : "<< recv_msg_size << "----\n";
      cout << "---" << inet_ntoa(clientaddr.sin_addr) << "----\n";
      cout << "---" << ntohs(clientaddr.sin_port)<< "----\n";
      cout << "---" << sockinfo.sinfo_assoc_id << "----\n";
      cout << "---" << sockinfo.sinfo_stream << "----\n";
      }


      sockinfo.sinfo_stream++;


      if (::sctp_sendmsg(sockfd, line, sizeof(line), (struct
      sockaddr*) &clientaddr, len, sockinfo.sinfo_ppid, sockinfo.sinfo_flags,
      sockinfo.sinfo_stream, 0, 0) < 0){
      char* errmsg = strerror (errno);
      cerr << "Error: cannot send data: " << errmsg <<"\n";
      }
      memset(line, 0x0, MSG_SIZE); // set line to all zeroes
      }
      }


      if (::close(sockfd) < 0){
      char* errmsg = strerror (errno);
      cout << "Socket closing is failed : " << errmsg <<"\n";
      }
      else{
      cout << "Socket closing is successful\n";
      }
      return 0;



      }


      Thank you