我尝试使用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
。
答案 0 :(得分:2)
您永远不会在父进程中关闭connfd
(当childpid!= 0时),并且您没有正确终止尝试循环的子进程。您的if块应如下所示:
if ((childpid = fork()) == 0) {
...
close(connfd);
exit(0);
}
else {
close(connfd);
}
但正如你所说,你想一次接受一个连接,你根本就不能分叉。
正如其他答案所示:
mesg[n]
&gt; = 0 n
recvfrom
和sendto
对于TCP来说过于苛刻,只需使用recv
和send
(甚至read
和write
)答案 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服务器,但是使用了recvfrom
和sendto
,它们专用于无连接协议(UDP)。
试试recv
和send
。也许这可能会有所帮助。