【问题标题】:Can I call socket send() from different threads?我可以从不同的线程调用套接字发送()吗?
【发布时间】:2015-04-27 13:40:48
【问题描述】:

如果我有一个名为ssocket,我可以在不同的线程中执行此操作吗:

线程 1:

send(s, "Hello from Thread 1");

线程 2:

send(s, "Hello from Thread 2");

是否保证这两个字符串会一个接一个地放在发送缓冲区中(我不在乎哪个放在第一位),或者它们有可能混合在一起?

注意:也许这个问题的标题应该是:“Is socket send() thread safe”(但我不太确定线程安全是什么意思)。

【问题讨论】:

    标签: c++ windows multithreading sockets network-programming


    【解决方案1】:

    答案是否定的。一般send() 不保证数据是一块发送的。您总是需要检查send() 返回的值,以了解实际发送了多少字节。如果这小于缓冲区的大小(不是错误),则必须在循环中适当地再次调用send(),例如像这样:

    char *msg="Hello from thread 1";
    size_t pos;
    size_t currentBytes;
    size_t BytesToSend=strlen(msg);
    
    for (pos=0 ; pos < BytesToSend ; pos += currentBytes) {
        currentBytes = send(s, msg + pos, BytesToSend - pos, 0);
    
        if (currentBytes <= 0) {
           // error occurred (-1) or connection has been closed on remote site (0)
           return ...
        }
    }
    

    这意味着你的数据可能会分段到达,当从两个线程发送时,数据可能会混合在一起。

    另见send()参考,尤其是

    如果没有出错,send返回发送的总字节数,可以小于len参数中请求发送的字节数。

    【讨论】:

    • 我认为阻塞的send() 调用在发送数据之前不会返回!
    • @Tom 一个阻塞的 send() 在至少发送一些字节之前不会返回。无法保证在发送所有字节之前它会阻塞。见:stackoverflow.com/questions/2618736/…
    • @Jeremy Friesner WSASend() 怎么样,它只能发送部分数据吗? (WSASend() 处于阻塞模式,不使用重叠 I/O)。
    • 我没怎么用过 WSASend(),所以我只能建议阅读它的文档页面:msdn.microsoft.com/en-us/library/windows/desktop/…(尤其是备注部分)
    • 在阻塞模式下,send() 会阻塞,直到所有数据都发送完毕或发生错误。这是由 Posix 保证的。
    猜你喜欢
    • 2021-09-04
    • 2013-01-20
    • 2012-07-14
    • 2023-03-03
    • 2016-10-15
    • 1970-01-01
    • 2017-10-25
    • 2014-11-19
    • 2012-11-02
    相关资源
    最近更新 更多