Unix套接字:如何与一个“发送”呼叫发送真正的大数据?
题
我使用UNIX SCOKET用于数据传输(SOCK_STREAM模式)
我需要发送多于100k的字符的字符串。首先,我送一个字符串的长度 - 它的的sizeof(int)的字节。
length = strlen(s)
send(sd, length, sizeof(int))
然后我发送整个字符串
bytesSend = send(sd, s, length)
但我的惊喜 “bytesSend” 小于 “长度”。
请注意,这工作得很好,当我送没有那么大的字符串。 可能存在的系统调用“发送”一些限制,我已经错过了......
解决方案
在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;
}
在接收端,你可能会需要做同样的事情。
其他提示
您最初send()
电话是错误的。需要传递的send()中的数据的地址,即:
bytesSend = send(sd, &length, sizeof(int))
此外,该运行到一些经典风险,字节序,在各种平台上,等等。
的int
大小 不隶属于 StackOverflow