unix套接字:如何通过一个"发送"调用发送真正的大数据?

Nel*_*lly 1 unix sockets send

我正在使用unix scoket进行数据传输(SOCK_STREAM模式)

我需要发送一串超过100k的字符串.首先,我发送一个字符串的长度 - 它的sizeof(int)字节.

length = strlen(s)
send(sd, length, sizeof(int))
Run Code Online (Sandbox Code Playgroud)

然后我发送整个字符串

bytesSend = send(sd, s, length)
Run Code Online (Sandbox Code Playgroud)

但令我惊讶的是"bytesSend"小于"length".

请注意,当我发送不那么大的字符串时,这很好用.对于我一直缺少的系统调用"发送"可能存在一些限制......

Art*_*ius 11

send系统调用应该是快速的,因为程序可能有其他的东西有用的事情要做.当然,您不希望等待数据发送出去而另一台计算机发送回复 - 这将导致可怕的吞吐量.

所以,所有send的确是将一些数据排队等待发送并将控制返回给程序.内核可以将整个消息复制到内核内存中,但这会占用大量内核内存(不好).

相反,内核只会将尽可能多的消息排队.重新尝试发送剩余数据是程序的责任.

在您的情况下,使用循环来发送第一次未发送的数据.

while(length > 0) {
    bytesSent = send(sd, s, length);
    if (bytesSent == 0)
        break; //socket probably closed
    else if (bytesSent < 0)
        break; //handle errors appropriately
    s += bytesSent;
    length -= bytesSent;
}
Run Code Online (Sandbox Code Playgroud)

在接收端,您可能需要做同样的事情.