1

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

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

length = strlen(s)
send(sd, length, sizeof(int))

然后我发送整个字符串

bytesSend = send(sd, s, length)

但令我惊讶的是,“bytesSend”小于“length”。

请注意,当我发送不太大的字符串时,这可以正常工作。可能存在我一直缺少的系统调用“发送”的一些限制......

4

2 回答 2

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;
}

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

于 2009-10-16T12:50:05.410 回答
1

你最初send()的电话是错误的。您需要通过 send() 数据的地址,即:

bytesSend = send(sd, &length, sizeof(int))

此外,这会遇到一些经典风险,包括字节顺序、int各种平台上的大小等。

于 2009-10-16T12:49:08.667 回答