我想要一个事件驱动的,windows,c#,tcp客户端。
当读缓冲区中至少有35个字节时,我希望调用一个处理程序来读取那35个字节,从该“数据包”中获取一个长度值,然后对该第二个数据长度进行阻塞读取
答案 0 :(得分: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();
答案 1 :(得分:1)
要朝着正确的方向前进,请查看Socket.BeginReceive()
和Socket.BeginSend()
。
此外,here是微软有关如何使用上述功能的一系列示例。这帮助我开始了这些。
不幸的是,我看不到调用回调的选项,除非读缓冲区中至少有35个字节;只要收到任何内容,它就会被调用 - 即使它是零字节。但是,无论如何,交易对手可能不会逐字节地向您发送消息。
答案 2 :(得分:1)
我不相信BCL中有任何基于事件的套接字类,但如果你只是寻找比裸Socket
更高级别的东西,也许你应该研究{{ 3}}。它将为您处理基础流的缓冲,让您通过StreamReader
等访问它:
TcpClient client;
// ... construct, connect, etc ...
new StreamReader(client.GetStream());
如果您使用的是基于行的协议,则只需使用TcpClient
,但StreamReader.ReadLine()
也应该很容易适合您的目的。