为什么send()不会为关闭的TCP连接触发SIGPIPE?

时间:2018-04-03 16:28:15

标签: c linux sockets tcp

我正在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?

0 个答案:

没有答案