unix sockets:如何用“一个”发送真正的大数据;“发送”;呼叫

unix sockets:如何用“一个”发送真正的大数据;“发送”;呼叫,sockets,unix,send,Sockets,Unix,Send,我正在使用unix scoket进行数据传输(SOCK\u流模式) 我需要发送超过10万字符的字符串。首先,我发送一个字符串的长度——它是sizeof(int)字节 然后我发送整个字符串 bytesSend = send(sd, s, length) 但令我惊讶的是,“bytesSend”小于“length” 请注意,当我发送的字符串不太大时,这可以正常工作。 可能存在一些我丢失的系统调用“send”的限制…您最初的send()调用是错误的。您需要将数据的地址传递给send(),即: byte

我正在使用unix scoket进行数据传输(SOCK\u流模式)

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

然后我发送整个字符串

bytesSend = send(sd, s, length)
但令我惊讶的是,“bytesSend”小于“length”

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

您最初的
send()
调用是错误的。您需要将数据的地址传递给send(),即:

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

此外,这也会遇到一些经典的风险,比如endianness、各种平台上的
int
大小等等。

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

因此,
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;
}
while(长度>0){
bytesSent=发送(sd、s、长度);
if(bytesSent==0)
break;//套接字可能已关闭
else if(bytesSent<0)
break;//适当地处理错误
s+=字节数;
长度-=字节数;
}

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

我刚刚在这里发布此邮件时打印错误。。。在我的代码中,这个调用是正确的。似乎这是唯一的方法。谢谢你,呵呵。。。那是不是让我熬夜太晚了
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;
}