socket receive不能在for循环中

Socket receive can't be in for loop

我想以 32 位块发送 1GB 数据,所以在 for 循环中我正在做 send(client_sock, buffer, tinfo->bufferSize, 0); 这很好。但在那之后,我收到了在第一次迭代后抛出 error(如下所示)的响应。如果我把 recv 放在 for loop 的外面,那么它就可以正常工作。但是这样我就无法确保每个块是否都正确发送了。

我的问题是

  1. 为什么我们不能迭代 receive 而我们可以迭代
    send
  2. 可以不接收 for 吗?不用担心 关于是否每条消息都已发送?

N.B。 - 不能使用外部库,它是大学的 POC 项目。 'send 1 Gb of data in 32 bits chunk over socket'

void *tcpClient(void *arg) {
    struct thread_info * tinfo = (struct thread_info *)arg;
    char * buffer = (char *)malloc(sizeof(char)*(tinfo->bufferSize));
    memset(buffer, 'a', sizeof(char)*(tinfo->bufferSize));

    int client_sock = socket(AF_INET, SOCK_STREAM, 0);
    connect(client_sock, (struct sockaddr *)&(tinfo->server_addr), sizeof(struct sockaddr));

    long noOfChunks = oneGb/ tinfo->bufferSize;
    for (int j = 0; j < noOfChunks; ++j) {
        int totalBytesRcvd = 0;
        int bytesRcvd = 0;
        send(client_sock, buffer, tinfo->bufferSize, 0);
        while (totalBytesRcvd < tinfo->bufferSize)
        {
            if ((bytesRcvd = recv(client_sock, buffer, tinfo->bufferSize, 0)) <= 0)
                error("recv() failed or connection closed prematurely");
            totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */

        }
        printf(buffer); /* Print the echo buffer */
    }

    free(buffer);
}

我遇到的错误:

Signal: SIGPIPE (signal SIGPIPE)
Terminated due to signal 13

Signal: SIGPIPE 当您写入已被对等方关闭的连接时发生。

那么,你的对端已经关闭了连接。

解决方法:不要。

在这里告诉您的所有关于 send() 程序崩溃或在阻塞模式下返回短计数的信息都是无稽之谈。 Posix 要求它阻塞,直到所有数据都被传输或发生错误,而这正是正在发生的事情。

1) @EJP 的回答几乎是正确的,但让我改一下。 "Socket receive can be in for loop",除了效率低下和糟糕的方法外,它没有任何问题。如果服务器在您的循环仍处于活动状态时关闭连接,您可能会收到 SIGPIPE 错误。

显而易见的可能解决方案是将 receive 保持在循环之外,因为如果每个块都已发送则不需要确认(在大多数情况下。)

2) 如果使用 TCP,可以在 for 之外保持接收,OS 将注意是否按顺序发送块并且没有块丢失。因此,即使我们将 receive 移到循环外也没有问题。