简体   繁体   中英

Data not received back by client via socket [Transport endpoint is already connected]

I have two programs Node-A and Node-B, where Node-A is sending some char* data to Node-B and Node-B is sending an ack (char* data) to Node-A. ie, the clientNodeA_thread is sending data to Node-B's serverNodeB_thread. The code is as below:

NodeA

int main()
    {
      pthread_t clientNodeA, serverNodeA;

      usleep(3000000);
      pthread_create(&clientNodeA, NULL, clientNodeA_thread, "clientNodeA");
      pthread_create(&serverNodeA, NULL, serverNodeA_thread, "serverNodeA");
      usleep(100000000);

      pthread_join(clientNodeA, NULL);
      pthread_join(serverNodeA, NULL);
      return 0;
    }

    void* clientNodeA_thread(void* pString)
    {
        int connSock, in, i, ret, flags;
        struct sockaddr_in servaddr, NodeAaddr;
        struct sctp_status status;
        char buffer[MAX_BUFFER+1];
        /* Sample input*/
         strncpy(buffer, "FrmNodeAClt", 12);
         buffer[12]='\0';

         connSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

         if(connSock == -1)
           die("socket()");
         #if 0
         bzero( (void *)&NodeAaddr, sizeof(NodeAaddr) );
         NodeAaddr.sin_family = AF_INET;
         NodeAaddr.sin_port = htons(MY_PORT_NUM_NodeA2);
         NodeAaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
         #endif

         bzero( (void *)&servaddr, sizeof(servaddr) );
         servaddr.sin_family = AF_INET;
         servaddr.sin_port = htons(MY_PORT_NUM_NodeB);
         servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );



    ret = connect( connSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

         if(ret == -1)
            die("connect()");

           ret = sctp_sendmsg( connSock, (void *)buffer, (size_t)strlen(buffer),
                              NULL, 0, 0, 0, 0, 0, 0 );
        return 0;
    }

    void* serverNodeA_thread(void* pString)
    {
      int listenSock, connSock, ret, in , flags, i;
      struct sockaddr_in servaddr;
      struct sockaddr_in src_addr;
      struct sctp_initmsg initmsg;
      int addr_len = 0;

      listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );
      bzero( (void *)&servaddr, sizeof(servaddr) );
      servaddr.sin_family = AF_INET;
      servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
      servaddr.sin_port = htons(MY_PORT_NUM_ENB2);

  ret = bind( listenSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

      /* Specify that a maximum of 5 streams will be available per socket */
      memset( &initmsg, 0, sizeof(initmsg) );
      initmsg.sinit_num_ostreams = 5;
      initmsg.sinit_max_instreams = 5;
      initmsg.sinit_max_attempts = 4;
      ret = setsockopt( listenSock, IPPROTO_SCTP, SCTP_INITMSG, 
                         &initmsg, sizeof(initmsg) );

      listen( listenSock, 5 );

      while( 1 ) {

      char buffer[MAX_BUFFER + 1];
      int len ;  

      bzero(buffer, MAX_BUFFER + 1);

      printf("Awaiting a new connection\n");

      connSock = accept( listenSock, (struct sockaddr *)NULL, (int *)NULL );
      if(connSock == -1)
          die("accept()");
        else
          printf("New client connected....\n");
          addr_len = sizeof (src_addr);
          recvfrom(connSock, buffer, sizeof(buffer), 0, &src_addr, &addr_len);
          printf("Received data from NodeB : %s\n", (char*)buffer);
      }
    }

NodeB

int connSock;

/*NodeA context maintenance */
struct NodeAStruct {
  char ipAddr[20];
  unsigned int portNum;
};

static int NodeAInstCount;
struct NodeAStruct NodeAInst[7];

int main()
{

  pthread_t clientNodeA, serverNodeA;

  pthread_create(&serverNodeA, NULL, serverNodeB_thread, "serverNodeA");
  usleep(10000000);

  pthread_join(clientNodeA, NULL);
  pthread_join(serverNodeA, NULL);

  return 0;
}

void* serverNodeB_thread(void* pString)
{
  int listenSock, ret, flags, i;
  struct sockaddr_in src_addr;
  struct sockaddr_in servaddr;
  struct sctp_initmsg initmsg;
  struct sctp_event_subscribe events;
  struct sctp_sndrcvinfo sndrcvinfo;
  char sendBuffer[MAX_BUFFER+1];
  unsigned int NodeA_PORT_NUM;
  char* NodeA_IP_ADDR;  
  char  from_ip[1024] = "", myip[2014] = "";
  int addr_len = 0;

  listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP ); 
  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
  //servaddr.sin_addr.s_addr = htonl("127.0.0.1");
  servaddr.sin_port = htons(MY_PORT_NUM_NodeB);

  ret = bind( listenSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

  /* Specify that a maximum of 5 streams will be available per socket */
  memset( &initmsg, 0, sizeof(initmsg) );
  initmsg.sinit_num_ostreams = 5;
  initmsg.sinit_max_instreams = 5;
  initmsg.sinit_max_attempts = 4;
  ret = setsockopt( listenSock, IPPROTO_SCTP, SCTP_INITMSG, 
                     &initmsg, sizeof(initmsg) );

  listen( listenSock, 5 );

  while( 1 ) {

  char buffer[MAX_BUFFER + 1];
  int len ;  

  bzero(buffer, MAX_BUFFER + 1);
  printf("Awaiting a new connection\n");

  connSock = accept( listenSock, (struct sockaddr *)NULL, (int *)NULL );
  if(connSock == -1)
      die("accept()");
    else
    {
      printf("New client connected....\n");     
      addr_len = sizeof (src_addr);
      recvfrom(connSock, buffer, sizeof(buffer), 0, &src_addr, &addr_len);

      printf("Received message: %s from NodeA IP: %s Port: %u  \n", (char*)buffer, inet_ntop(AF_INET, &src_addr.sin_addr, from_ip, sizeof(from_ip)), ntohs(src_addr.sin_port));
      strcpy(NodeAInst[NodeAInstCount].ipAddr, inet_ntop(AF_INET, &src_addr.sin_addr, from_ip, sizeof(from_ip)));
      NodeAInst[NodeAInstCount].portNum = ntohs(src_addr.sin_port);
      printf("NodeA instance [%d] added \n", NodeAInstCount);

     /* Send data to NodeA*/
     strncpy(sendBuffer, "From NodeB", 12);
     sendBuffer[12]='\0';
     NodeA_PORT_NUM = NodeAInst[NodeAInstCount].portNum;
     usleep(10000000);
     ret = sctp_sendmsg( connSock, (void *)sendBuffer, (size_t)strlen(sendBuffer),
                          NULL, 0, 0, 0, 0, 0, 0 );
     if(ret>0) {
        printf("Data sent to NodeA \n");
     }
     else {
        printf("Sending data to NodeA failed");
     }
     usleep(6000000);
     NodeAInstCount++;

    }
  }
}

I am able to send data from Node-A client to Node-B server, and the Node-B is also able to send Ack data (as verified in Wireshark), but it is not reaching Node-A receive code.

Any help in this regard would be highly helpful.

The problem is that you bind the client A socket to the local address, but you don't bind the passive server socket.

Don't bind client sockets, there's often no need for that. You do need to bind the server sockets locally though, or the system will just bind it to a random port when you call listen .

Issue resolved! I just moved the NodeA's socket creation and bind part to the main function so that it would be shared by both client and server threads, and the client and server threads would just do the send and receive functionality.

Thanks @Joachim Pileborg

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM