套接字接收不能进行for循环

时间:2018-02-28 23:16:51

标签: c sockets pointers receiver

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

我的问题是

  1. 当我们可以迭代时,为什么我们无法迭代receive send
  2. 是否可以保持收到for并且不用担心 关于每封邮件是否已发送?
  3. N.B。 - 不能使用外部图书馆,它是大学的POC项目。 '通过套接字在32位块中发送1 Gb数据'

    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
    

2 个答案:

答案 0 :(得分:2)

当您写入已经被对等方关闭的连接时,会发生

Signal: SIGPIPE

所以,你的同伴关闭了连接。

解决方案:不要。

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

答案 1 :(得分:0)

1)@ EJP的答案几乎是正确的,但让我重新说一下。 &#34;套接字接收可以是for循环&#34;,它没有任何问题,除了它是低效和坏的方法。如果服务器在您的循环仍处于活动状态时关闭连接,则可能会出现SIGPIPE错误。

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

2)保持接收在for外是可以的,如果使用了TCP,如果按顺序发送块并且没有丢失块,操作系统将会小心。因此,即使我们将receive移到循环之外也没关系。