Linux Socket通信时,客户端和服务端发送信息时,关闭客户端进程时,服务端会关闭这个socket连接的原因
在尝试使用Linux Socket通信时,客户端和服务端发送信息时,关闭客户端进程时,服务端会关闭这个socket连接的原因,代码如下:
服务端程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| while(true) { char buf[MAX_BUFFER]; char *return_msg = (char*)"got it"; memset(&buf, 0, sizeof(buf)); ssize_t read_bytes = read(client_socket, &buf, sizeof(buf)); if(read_bytes > 0) { printf("message from client fd %d: %s\n", client_socket, buf); write(client_socket, return_msg, sizeof(return_msg)); } else if(read_bytes == 0) { printf("client fd %d disconnect\n", client_socket); close(client_socket); break; } else { close(client_socket); errif(true, "Socket failed to read"); } }
|
客户端程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| while(true) { char buf[MAX_BUFFER]; memset(&buf, 0, sizeof(buf)); scanf("%s", buf); ssize_t write_types = write(client_socket, &buf, sizeof(buf)); if(write_types == -1) { printf("socket already disconnected, can't write anymore!\n"); break; } memset(&buf, 0, sizeof(buf)); ssize_t read_bytes = read(client_socket, &buf, sizeof(buf)); if(read_bytes > 0) { printf("message from server: %s\n", buf); } else if(read_bytes == 0) { printf("server has disconnected"); break; } else { close(client_socket); errif(true, "socket read error"); } }
|
可以观察到,通信过程为客户端通过scanf
函数发送信息,发送后收到服务端的回复。
遇到的问题/现象如下:当关闭客户端程序进程时,服务端程序自动输出client fd 4 disconnect
原因:强行关闭客户终端时,client
进程交付给init
进程,当init
进程查询到client
后将其杀掉,但是在杀掉之前,由于关掉了终端(主要是关掉了输入缓冲区),导致本来阻塞中的scanf
返回EOF
,程序得以继续执行发送操作。服务器发现client
有消息传入,但是在尝试回应client
的时候client
被初始进程杀掉。然后就变成了给已经关闭的socket
发送数据。这个时候服务端的read
会返回0
,表示EOF
,接着调用read_bytes
的分支,输出结果
注:不是因为scanf
返回EOF
,写入了write
函数,导致服务端的read
读到0
修改客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| std::ofstream outfile("../temp/output.txt"); while(true) { char buf[MAX_BUFFER]; memset(&buf, 0, sizeof(buf)); char temp[MAX_BUFFER]; memset(&temp, 0, sizeof(temp)); scanf("%s", temp); outfile << "exe continue" << std::endl; strncpy(buf, "hello", MAX_BUFFER - 1); ssize_t write_types = write(client_socket, &buf, sizeof(buf)); if(write_types == -1) { printf("socket already disconnected, can't write anymore!\n"); break; } memset(&buf, 0, sizeof(buf)); ssize_t read_bytes = read(client_socket, &buf, sizeof(buf)); if(read_bytes > 0) { printf("message from server: %s\n", buf); } else if(read_bytes == 0) { printf("server has disconnected"); break; } else { close(client_socket); errif(true, "socket read error"); } } outfile.close();
|
此时写入的buf
一直都是hello
,强行关闭进程,强行关闭进程也会出现以上现象。而且文件输出结果不会包含停止进程的那次输出,说明不会执行到下一步。
注2:当输入数据大于MAX_BUFFER
的大小时,会分多次发送。