【问题标题】:Event driven TCP Client事件驱动的 TCP 客户端
【发布时间】:2012-07-29 21:27:52
【问题描述】:

我想要一个事件驱动的、windows、c#、tcp 客户端。

当读取缓冲区中至少有 35 个字节时,我希望调用一个处理程序来读取这 35 个字节,从该“数据包”中获取一个长度值,然后对第二个数据长度进行阻塞读取.

【问题讨论】:

  • 流是流。任何大于一个字节的结构的解释都在您的管辖范围内。您的代码需要组装消息头,解析它,累积剩余的消息数据,缓冲任何额外的字节以供以后解释,...。可悲的是,19 世纪赢得了网络协议战争。
  • 哇...... Kernigan 和 Ritchie 没有提到失去协议战争......
  • 感谢 ceykooo 和 ikh。我会深入研究您的建议。
  • 其实现在是 21 世纪 ;-)

标签: c# events tcp client


【解决方案1】:

要朝着正确的方向前进,请查看Socket.BeginReceive()Socket.BeginSend()

另外,here 是 Microsoft 提供的一系列方便的示例,用于说明如何使用上述功能。这帮助我开始使用这些。

不幸的是,除非读取缓冲区中至少有 35 个字节,否则我看不到调用回调的选项;每当收到任何内容时都会调用它——即使它是零字节。但是,交易对手可能不会一个字节一个字节地给你发送消息。

【讨论】:

    【解决方案2】:

    我认为 BCL 中没有任何基于事件的套接字类,但如果您只是在寻找比纯 Socket 更高级别的东西,也许您应该研究一下 TcpClient。它将为您处理底层流的缓冲,让您通过StreamReader 等访问它:

    TcpClient client;
    // ... construct, connect, etc ...
    new StreamReader(client.GetStream());
    

    如果您使用的是基于线路的协议,您只需要使用StreamReader.ReadLine(),但StreamReader.Read() 也应该很容易满足您的目的。

    【讨论】:

      【解决方案3】:

      有一个相对较新的项目基本上提供了这个:https://github.com/clariuslabs/reactivesockets

      来自他们的页面:

      实现了一个非常易于使用的基于 IObservable 的套接字 API。它允许非常简单的协议实现,例如:

      var client = new ReactiveClient("127.0.0.1", 1055);
      
      // The parsing of messages is done in a simple Rx query over the receiver observable
      // Note this protocol has a fixed header part containing the payload message length
      // And the message payload itself. Bytes are consumed from the client.Receiver 
      // automatically so its behavior is intuitive.
      IObservable<string> messages = from header in client.Receiver.Buffer(4)
                                     let length = BitConverter.ToInt32(header.ToArray(), 0)
                                     let body = client.Receiver.Take(length)
                                     select Encoding.UTF8.GetString(body.ToEnumerable().ToArray());
      
      // Finally, we subscribe on a background thread to process messages when they are available
      messages.SubscribeOn(TaskPoolScheduler.Default).Subscribe(message => Console.WriteLine(message));
      client.ConnectAsync().Wait();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-16
        • 1970-01-01
        • 2018-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-21
        相关资源
        最近更新 更多