我正在Linux中编写一个简单的服务器和一个基于TCP连接的简单客户端。我发现当服务器关闭时,来自客户端的第一个send()
将成功(并返回字节发送)。只有来自客户端的第二个send()
才会触发SIGPIPE。
以下代码说明了这种现象。客户端连接到服务器后,我关闭服务器的套接字,然后让客户端向服务器发送两个连续的消息。第一个send()
将成功,而第二个send()
将触发SIGPIPE。
服务器代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERVER_SOCK 32413
#define LISTEN_BACKLOG 20
int main() {
int server_sock, client_sock;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
// Create socket
server_sock = socket(AF_INET, SOCK_STREAM, 0);
// Set address and port
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(SERVER_SOCK);
// Bind to port and begin listening
bind(server_sock, (struct sockaddr*) &server_addr, sizeof(server_addr));
listen(server_sock, LISTEN_BACKLOG);
printf("Server is listening\n");
// Accept client socket
client_sock = accept(server_sock, (struct sockaddr*) &client_addr, &client_len);
printf("Connection accepted\n");
// Close all socket after pressing enter
printf("Press enter to close server");
getchar();
close(server_sock);
close(client_sock);
return 0;
}
客户代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERVER_SOCK 32413
int main() {
// Create socket
int sock = socket(AF_INET, SOCK_STREAM, 0);
// Connect to server
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(SERVER_SOCK);
connect(sock, (struct sockaddr*) &server_addr, sizeof(server_addr));
printf("Connected\n");
// Send message after pressing enter
printf("Press enter to send message");
getchar();
printf("1st send: %ld\n", send(sock, "one", 3, 0));
printf("2nd send: %ld\n", send(sock, "two", 3, 0));
close(sock);
return 0;
}
服务器的输出是:
Server is listening
Connection accepted
Press enter to close server
客户的输出是:
Connected
Press enter to send message
1st send: 3
那是怎么回事?为什么第一个send()
成功了?是不是应该触发SIGPIPE?