7

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

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

4

3 回答 3

4

有一个相对较新的项目基本上提供了这个: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();
于 2013-05-03T13:59:54.430 回答
1

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

此外,这里有一系列来自 Microsoft 的方便示例,用于说明如何使用上述功能。这帮助我开始使用这些。

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

于 2012-08-01T02:15:44.420 回答
1

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

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

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

于 2012-08-01T02:26:05.937 回答