Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event driven TCP Client

I want a event-driven, windows, c#, tcp client.

When there are at least 35 bytes in the read buffer, I want a handler to be called that will read those 35 bytes, grab a length value from that "packet", then do a blocking read for that second length of data.

like image 712
Chuck Bland Avatar asked Aug 01 '12 01:08

Chuck Bland


2 Answers

There's a relatively new project that essentially provides this: https://github.com/clariuslabs/reactivesockets

From their page:

Implements a very easy to use sockets API based on IObservable. It allows very simple protocol implementations such as:

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();
like image 115
gregmac Avatar answered Oct 27 '22 10:10

gregmac


I don't believe there is any event-based socket class available in the BCL, but if you're just looking for something a bit higher level than a bare Socket, perhaps you should look into TcpClient. It will handle buffering the underlying stream for you, letting you access it through a StreamReader and the like:

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

If you were using a line based protocol, you'd only need to use StreamReader.ReadLine(), but StreamReader.Read() should easily suit your purposes as well.

like image 23
ceyko Avatar answered Oct 27 '22 11:10

ceyko