What is the current standard of practice for implementing an async socket client?

I am looking for best practices to meet the following requirements:

  • A structure that processes multiple client sockets in asynchronous mode.
  • Each incoming message protocol determines that each message has a format string and is marked in full by the string character "\ n".
  • I have full control over the client side, but not with the server. The server receives and sends string messages with a line symbol to mark the end of the message.
  • I want to be able to send messages through each connected socket at any given time (each socket can receive and send messages).
  • Incoming messages must be sent via a callback.
  • I want to be able to choose in my implementation whether all incoming full messages from all connected sockets are routed to one callback or each socket client implements its own callback.
  • I connect a maximum of 4 clients / sockets. Therefore, I am looking for offers that use such a limited number of sockets, but they are able to manage all of these at the same time.

I wonder if the environment in which I use BeginReceive and EndReceive with the EndReceive implemented is the most advanced target set .Net 4.5. Is there a better solution, for example, using NetworkStream or other API options? What really bothers me with implementing BeginReceive / EndReceive is that after EndReceive I need to call BeginReceive again and register the callback again. That sounds like a terrible amount of overhead to me. Why can't new async data be added at any time, and at the same time, a different context creates complete messages, which are then routed through the raised event?

The argument for using IAsyncResult is often indicated in the fact that stream processing is performed, but that is against the following: Using NetworkStream and just reading and writing to the stream. As mentioned, only text messages are exchanged, and each message on the protocol is marked with a full line symbol. A separate task / stream will poll the stream analyzer (based on the network stream) through ReadLine() . It could probably be easier, right?

Basically I ask a question, how to make the following code really asynchronous?

 public class SocketClient { private TcpClient client; private StreamReader reader; private StreamWriter writer; public event Action<string> MessageCallback; public SocketClient(string hostname, int port) { client = new TcpClient(hostname, port); try { Stream stream = client.GetStream(); reader = new StreamReader(stream); writer = new StreamWriter(stream); writer.AutoFlush = true; //Start Listener on port StartListener(); } catch (Exception e) { throw new Exception(e.ToString()); } } public void StartListener() { Task task = Task.Factory.StartNew(() => { while (true) { if (MessageCallback != null) { MessageCallback(reader.ReadLine()); } //Thread.Sleep(200); } }); } } 
+8
c # asynchronous sockets tcp networkstream
source share
2 answers

There is currently no standard or routine practice. You have a choice, each of which has advantages and disadvantages:

  • Wrap TAP methods in Task and use async / await .
    • Advantages: Simple enough.
    • Disadvantages: it is low; you need to manage all of the various async operations yourself in an "endless" loop, and also manage the control state for each connection.
  • Wrap the Socket *Async methods in Task and use async / await .
    • Advantages: Speed. This is the fastest and most scalable option.
    • Disadvantages: you still have β€œinfinite” low-level loops and state management, where the code is more complex than option (1).
  • Convert socket completion to Rx events .
    • Advantages: you can encapsulate "infinite" loops and treat terminations as a stream of events.
    • Disadvantages: There is a complex learning curve for Rx, and this is not a simple use case. Managing the state of each connection can be difficult.
  • Convert socket completion to TPL data stream .
    • Advantages: (same as Rx): encapsulating loops and receiving a data stream.
    • Disadvantages: The learning curve is easier than Rx, but you still have sophisticated state management for each connection.
  • Use an existing library, such as the Nito.Async library, which provides EAP socket classes.
    • Advantages: very easy to use; all this event, and there are no multithreaded problems. In addition, state management stunts are made for you.
    • Disadvantages: not scalable, as well as solutions at a lower level.

For your situation (a few hundred messages per second in less than a hundred sockets), I would recommend using my Nito.Async library. This is the easiest of these options to work with.

As for your protocol, you will have to manually parse \n and do your own buffering. (This is true for all of the above options).

+11
source share

As per my recommendation, use the new Async XXXReceive and 'XXXSend' form (where XXX stands for Begin and End ), the new available ReceiveAsync and SendAsync methods that use SocketAsyncEventArgs to send socket and other information about callback event handlers.

I saw a good working example of a socket client and server in the msdn archive, which was scaled up to 500 connections (since I tested in one of its adaptation to the project), but currently I can not find this link from googling. but here is another link from the msdn archive on the same topic, I hope this helps you - Get closer to the wire with high-performance sockets in .NET ..

UPDATE

First of all, I can provide you only with the idea of ​​the final implementation and, if possible, short fragments of code. ok here i go with more details

I think you can go to the last paragraph link .;)

Let me single out once because I want, I said SendAsync and ReceiveAsync not BeginReceive/EndReceive and BeginSend/EndSend ie BeginSend/EndSend Asynchronous Pattern (EAP)

The advantage of using the Async form of Socket methods is that they are an exception-free approach to socket programming, which can be faster than BeginSend / EndSend methods.

Here is a link to a sample I found useful for up to 500 PARALLEL connections - Networking Examples for .NET v4.0

To use await / async for .NET 4.5. Here is a .NET 4.5 code snippet that shows the use of the WebSocket class, which can also be adapted to Socket implementations - WebSockets protocol support (I think WebSocket AspNetWebSocketContext will be Socket SocketAsyncEventArgs )

I found Waiting for socket operations to sample code from MSDN β€” a parallel blogging command that can be useful for implementing await / async from the .NET 4.5 platform.

Hope this is helpful to you.

+1
source share

All Articles