0

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?

TsReaper
  • 845
  • 7
  • 19

0 Answers0