【问题标题】:unix sockets: how to send really big data with one "send" call?unix 套接字:如何通过一个“发送”调用发送真正的大数据?
【发布时间】:2010-12-07 08:41:55
【问题描述】:

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

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

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

然后我发送整个字符串

bytesSend = send(sd, s, length)

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

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

【问题讨论】:

    标签: sockets unix send


    【解决方案1】:

    您最初的send() 呼叫是错误的。你需要传递send()数据的地址,即:

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

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

    【讨论】:

    • 我刚刚在发布此内容时在这里打印错误...在我的代码中调用是正确的..
    【解决方案2】:

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

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

    【讨论】:

    • 似乎这是唯一的方法。谢谢
    • 呵呵...所以让我熬夜太晚了
    猜你喜欢
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 2012-10-13
    • 2020-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多