I'm writing a simple server and a simple client based on TCP connection in Linux. I discover that when the server is closed, the first following send()
from the client will be successful (and return the bytes send). Only the second following send()
from the client will trigger SIGPIPE.
The following code illustrates this phenomenon. After the client is connected to the server, I close the socket of the server, and then let the client send two successive messages to the server. The first send()
will be successful, while the second send()
will trigger SIGPIPE.
Server code:
#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;
}
Client code:
#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;
}
The output of the server is:
Server is listening
Connection accepted
Press enter to close server
The output of the client is:
Connected
Press enter to send message
1st send: 3
So what's going on? Why is the first send()
successful? Isn't it supposed to trigger SIGPIPE?