客户端关闭连接时,服务器套接字完成

时间:2014-08-04 15:53:17

标签: c++ sockets

我尝试使用C ++创建服务器套接字,以便一次接受一个客户端连接。程序成功创建服务器套接字并等待传入​​连接,但是当客户端关闭连接时,程序将无休止地循环。否则,如果连接中断,它将继续按预期等待新连接。知道为什么会这样吗?感谢

这是我的C ++服务器代码:

   int listenfd, connfd, n;
   struct sockaddr_in servaddr, cliaddr;
   socklen_t clilen;
   pid_t     childpid;
   char mesg[1000];

   listenfd = socket(AF_INET, SOCK_STREAM, 0);

   bzero(&servaddr, sizeof(servaddr));
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
   servaddr.sin_port = htons(32000);
   bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

   listen(listenfd, 1024);

    while (true) {
        clilen = sizeof(cliaddr);
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);

        if ((childpid = fork()) == 0) {
            close (listenfd);

            while (true) {
                n = recvfrom(connfd, mesg, 1000, 0, (struct sockaddr *)&cliaddr, &clilen);
                sendto(connfd, mesg, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));

                mesg[n] = 0;
                printf("%d: %s \n", n, mesg);

                if (n <= 0) break;
            }
            close(connfd);
        }
    }

由于某种原因,当客户端关闭连接时,即使使用-1:子句,程序也会继续打印if-break

4 个答案:

答案 0 :(得分:2)

您永远不会在父进程中关闭connfd(当childpid!= 0时),并且您没有正确终止尝试循环的子进程。您的if块应如下所示:

if ((childpid = fork()) == 0) {
    ...
    close(connfd);
    exit(0);
}
else {
    close(connfd);
}

正如你所说,你想一次接受一个连接,你根本就不能分叉。

正如其他答案所示:

  • 如果不测试mesg[n]&gt; = 0
  • ,请不要使用n
  • recvfromsendto对于TCP来说过于苛刻,只需使用recvsend(甚至readwrite

答案 1 :(得分:1)

mesg[n] = 0;

当n <0时,这会中断,即。插座关闭

答案 2 :(得分:1)

问题是你的“n”和recvfrom。您正在使用TCP客户端,因此recvfrom将不会返回正确的值。

试着看看: How to send and receive data socket TCP (C/C++)

编辑1:

答案 3 :(得分:0)

您已经编写了一个TCP服务器,但是使用了recvfromsendto,它们专用于无连接协议(UDP)。

试试recvsend。也许这可能会有所帮助。