为什么我的简单 C 服务器在客户端关闭连接时退出?
Why my simple C server exits when the client closes connection?
#include <stdio.h>
#include <stdlib.h> /* exit() */
#include <strings.h> /* bzero(), bcopy() */
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
int main(int argc, char **argv){
int sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in my_addr;
bzero(&my_addr,sizeof my_addr);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(9999);
my_addr.sin_addr.s_addr = INADDR_ANY;
int res;
res = bind(sockfd,(struct sockaddr *)&my_addr,sizeof (struct sockaddr_in));
res = listen(sockfd,5);
while (1) { // shouldn't this while cycle "keep alive" the server to wait for new clients?
struct sockaddr_in cli_addr;
bzero(&cli_addr,sizeof cli_addr);
socklen_t cli_size = sizeof (struct sockaddr_in);
int clisockfd = accept(sockfd,(struct sockaddr *)&cli_addr,&cli_size);
while (1) {
char buf[100] = "";
int b_recv = recv(clisockfd, buf, 100, 0);
printf("%d %d\n",sockfd,b_recv);
printf("%s\n",buf);
char string[] = "test";
send(clisockfd,string,sizeof string,0))
}
}
}
如果我用 netcat 测试我的服务器,如果我关闭 netcat,服务器就会退出。为什么?外部 while 循环不应该让它保持活动状态吗?为什么以及如何避免服务器关闭?
如果您仔细检查,当您从客户端关闭连接时,服务器将以 SIGPIPE
信号终止。
发生这种情况是因为您没有检查关闭连接事件,而是试图写入关闭的连接。
当 recv
return 0
时,您不应尝试写入已连接的套接字。相反,您应该关闭套接字并跳出内部 recv
/send
循环。
while (1) {
char buf[100] = "";
int b_recv = recv(clisockfd, buf, 100, 0);
printf("%d %d\n",clisockfd,b_recv); // Print the connection socket instead
if (b_recv <= 0) {
// Error or closed connection
close(clisockfd);
break; // Go back to the outer loop, wait for new connections
}
printf("%s\n",buf);
char string[] = "test";
send(clisockfd,string,sizeof string,0))
}
#include <stdio.h>
#include <stdlib.h> /* exit() */
#include <strings.h> /* bzero(), bcopy() */
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
int main(int argc, char **argv){
int sockfd = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in my_addr;
bzero(&my_addr,sizeof my_addr);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(9999);
my_addr.sin_addr.s_addr = INADDR_ANY;
int res;
res = bind(sockfd,(struct sockaddr *)&my_addr,sizeof (struct sockaddr_in));
res = listen(sockfd,5);
while (1) { // shouldn't this while cycle "keep alive" the server to wait for new clients?
struct sockaddr_in cli_addr;
bzero(&cli_addr,sizeof cli_addr);
socklen_t cli_size = sizeof (struct sockaddr_in);
int clisockfd = accept(sockfd,(struct sockaddr *)&cli_addr,&cli_size);
while (1) {
char buf[100] = "";
int b_recv = recv(clisockfd, buf, 100, 0);
printf("%d %d\n",sockfd,b_recv);
printf("%s\n",buf);
char string[] = "test";
send(clisockfd,string,sizeof string,0))
}
}
}
如果我用 netcat 测试我的服务器,如果我关闭 netcat,服务器就会退出。为什么?外部 while 循环不应该让它保持活动状态吗?为什么以及如何避免服务器关闭?
如果您仔细检查,当您从客户端关闭连接时,服务器将以 SIGPIPE
信号终止。
发生这种情况是因为您没有检查关闭连接事件,而是试图写入关闭的连接。
当 recv
return 0
时,您不应尝试写入已连接的套接字。相反,您应该关闭套接字并跳出内部 recv
/send
循环。
while (1) {
char buf[100] = "";
int b_recv = recv(clisockfd, buf, 100, 0);
printf("%d %d\n",clisockfd,b_recv); // Print the connection socket instead
if (b_recv <= 0) {
// Error or closed connection
close(clisockfd);
break; // Go back to the outer loop, wait for new connections
}
printf("%s\n",buf);
char string[] = "test";
send(clisockfd,string,sizeof string,0))
}