【问题标题】:.NET C# socket send on two different threads.NET C# 套接字在两个不同的线程上发送
【发布时间】:2016-05-26 11:39:40
【问题描述】:

我有一个套接字,我在一个线程中接收和发送。但是,还有另一个线程可以定期使用套接字发送数据。目前,我正在使用共享对象来锁定我的Socket.send() 操作。这个锁有必要吗?如果是,即使我只从一个线程接收,我是否也需要锁定我的接收方法?

例如在 Thread1 中:

//...some code
 while (offset< len)
    {
       currentBytesRead += Client.Receive(buf, offset, len - offset, SocketFlags.None);
    }
//...some more code...
lock (lockObject)
    {
         Client.Send(outputByte);
    }

在线程 2 中:

    lock (lockObject)
    {
         Client.Send(outputByte);
    }

【问题讨论】:

    标签: c# multithreading sockets


    【解决方案1】:

    正如Socket 类的文档中所述,此类的实例是线程安全的。因为套接字代表双工连接 - 您可以在不同的线程上安全地发送和接收。您也可以在不加锁的情况下从多个线程发送数据,但请注意,在这种情况下不能保证顺序(因此,如果您使用多个发送操作发送单个逻辑结构 - 您需要锁定它们以免相互干扰)。

    但是请注意,如果您对收到的某些数据做出反应,通过发送一些数据作为响应 - 您需要锁定整个接收-发送块,并锁定来自另一个线程的发送。

    【讨论】:

    • if you react on some data received by sending some data in response - you need to lock the whole receive-send block, and lock sends from another thread - 所以如果我在线程 A 中接收数据,以某种方式处理它,并基于该处理,发回响应,我需要锁定整个接收发送块吗?只有当网络主机期待某个响应时,这才是正确的?
    • 是的,否则您可能会从接收和发送之间的另一个(第二个)线程获得该发送,并且您的客户会将其解释为对其原始请求的响应。是的,如果客户期望对他的原始请求有任何回应,那是真的。您可以通过使用一些唯一标识符 (guid) 标记每个请求并在发回响应时 - 包括请求的 id 来解决此问题。然后客户端可以区分这个响应是为哪个请求创建的。
    【解决方案2】:

    套接字是线程安全的,因此在您的示例中不需要锁。

    【讨论】:

    • 所以单个socket.send操作保证在其他线程的socket.send之前返回?上下文切换不会破坏缓冲区中的数据吗? IE。我有array1 = [0,0]和array2 = [1,1],我在thread1上调用socket.send(array1),在thread2上调用socket.send(array2),接收器保证接收array1和array2他们不可能以某种随机顺序接收几个字节的array1和array2?
    • 两条消息都以默认分隔符(我认为它的 \r\n)结尾。
    • 没有默认分隔符。
    猜你喜欢
    • 2017-10-25
    • 1970-01-01
    • 2013-02-28
    • 2016-09-29
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    相关资源
    最近更新 更多