简体   繁体   English

客户端通过套接字未收到数据[传输端点已连接]

[英]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. 我有两个程序Node-A和Node-B,其中Node-A正在向Node-B发送一些char *数据,而Node-B正在向Node-A发送ack(char *数据)。 ie, the clientNodeA_thread is sending data to Node-B's serverNodeB_thread. 即,clientNodeA_thread正在向Node-B的serverNodeB_thread发送数据。 The code is as below: 代码如下:

NodeA 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. 我能够将数据从Node-A客户端发送到Node-B服务器,Node-B也能够发送Ack数据(在Wireshark中验证),但它没有到达Node-A接收代码。

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. 问题是您将客户端A套接字绑定到本地地址,但您不绑定被动服务器套接字。

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 . 确实需要在本地绑定服务器套接字,或者系统将在您调用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. 我刚刚移动了NodeA的套接字创建并将部分绑定到main函数,以便客户端和服务器线程共享它,客户端和服务器线程只会执行发送和接收功能。

Thanks @Joachim Pileborg 谢谢@Joachim Pileborg

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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