在TCP套接字连接期间通过对等方重置连接?

时间:2016-09-27 07:46:33

标签: c sockets tcp client-server ipc

我正在创建一个小型客户端 - 服务器应用程序,其中服务器在接受后分叉子进程,在客户端连接到它时发送多个连接,发送消息并接收响应。以下是我的代码片段: - client.c

char buffer [256];

portno=5001;    

   /* Create a socket point */
   sockfd = socket(AF_INET, SOCK_STREAM, 0);

   if (sockfd < 0) {
      perror("ERROR opening socket");
      exit(1);
   }


   bzero((char *) &serv_addr, sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_port = htons(portno);

   /* Now connect to the server */
   if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
      perror("ERROR connecting");
      exit(1);
   }

   /* Now ask for a message from the user, this message
      * will be read by server
   */
while(1)
{   
   printf("Please enter the message: ");
   bzero(buffer,256);
   fgets(buffer,255,stdin);
   /* Send message to the server */
   n = write(sockfd, buffer, strlen(buffer));

   if (n < 0) {
      perror("ERROR writing to socket");
      exit(1);
   }

   /* Now read server response */
   bzero(buffer,256);
   n = read(sockfd, buffer, 255);
    if(n==0)
    {
      perror("nothing to read");
    }

   if (n < 0) {
      perror("ERROR reading from socket");
      exit(1);
   }

   printf("%s\n",buffer);
}

- server.c

int main( int argc, char *argv[] ) {
   int sockfd, newsockfd, portno, clilen;
   char buffer[256];
   struct sockaddr_in serv_addr, cli_addr;
   int n, pid;

   /* First call to socket() function */
   sockfd = socket(AF_INET, SOCK_STREAM, 0);

   if (sockfd < 0) {
      perror("ERROR opening socket");
      exit(1);
   }

   /* Initialize socket structure */
   bzero((char *) &serv_addr, sizeof(serv_addr));
   portno = 5001;

   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = INADDR_ANY;
   serv_addr.sin_port = htons(portno);

   /* Now bind the host address using bind() call.*/
   if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
      perror("ERROR on binding");
      exit(1);
   }

   /* Now start listening for the clients, here
      * process will go in sleep mode and will wait
      * for the incoming connection
   */

   listen(sockfd,5);
   clilen = sizeof(cli_addr);

   while (1) {
      newsockfd = accept(sockfd, (struct sockaddr *)NULL,NULL);

      if (newsockfd < 0) {
         perror("ERROR on accept");
         exit(1);
      }

      /* Create child process */
      pid = fork();

      if (pid < 0) {
         perror("ERROR on fork");
         exit(1);
      }



 if (pid == 0) 
 {
     while(1)
     {
     /* This is the client process */
     close(sockfd);
     doprocessing(newsockfd);
   /**  exit(0); **/
     }
 }
      else {
         close(newsockfd);
      }

   } /* end of while */
}


void doprocessing (int sock) {
   int n;
   char buffer[256];
   bzero(buffer,256);
   n = read(sock,buffer,255);
       if(n==0)
    {
      perror("nothing to read");
    }

   if (n < 0) {
      perror("ERROR reading from socket");
      exit(1);
   }

   printf("Here is the message: %s\n",buffer);
   n = write(sock,"I got your message",18);

   if (n <= 0) {
      perror("ERROR writing to socket");
      exit(1);
   }

}

当我运行两者时,O / P跟随:

Please enter the message: arjun
I got your message
Please enter the message: gaur
ERROR reading from socket: Connection reset by peer

请帮助我们解决此问题

3 个答案:

答案 0 :(得分:1)

会发生什么:

  1. 服务器开始监听。
  2. 客户端连接到侦听服务器。
  3. 流程服务客户端的服务器分支。
  4. 客户端发送数据。
  5. 3月份的服务流程从客户收到日期并打印出来。
  6. 服务流程截至3.向客户发送回复。
  7. 服务流程截至3.存在/结束,并且此接受的套接字(客户端的对等体)将关闭。
  8. 客户收到回复并打印出来。
  9. 自3月起,客户端尝试向服务流程发送更多数据。
  10. 客户端尝试从3 ..
  11. 开始,从服务流程中读取更多数据
  12. 步骤10.失败,因为3的服务过程已经结束(步骤7)

答案 1 :(得分:1)

分叉子进程正在退出而不关闭newsockfd。在一些导致连接重置而不是有序关闭的平台上。

您还需要检查recv()的结果为零并正确处理,即不是错误,并且您还需要正确使用正返回值,例如而不是

printf("%s\n",buffer);

应该是

printf("%.*s\n",n,buffer);

答案 2 :(得分:-1)

您的客户这样做:

  • 连接到服务器
  • 将一些数据发送到服务器
  • 从服务器接收一些数据
  • 将一些数据发送到服务器
  • 从服务器接收一些数据
  • ...

但您的服务器执行此操作(可能同时使用多个连接):

  • 等待连接
  • 从客户端收到一些东西
  • 向客户发送一些内容
  • 关闭连接(退出连接打开的唯一进程)

因此服务器在客户端即将发送更多数据时关闭连接,并且客户端因服务器关闭连接而收到错误。

您需要让服务器继续在循环中接收和发送数据(因此它可以在同一连接上多次发生),或者让客户端在每次想要发送内容时建立新连接。