Socket communication routines, either synchronous or asynchronous implementation, the routine is always the same, that is, the server opens a thread listening client socket, the client creates a socket to connect to the server's listening port, the server receives the client socket, In creating a thread that is responsible for communicating with the client thread (send receive data), there is a misconception that the listener socket is not communicating with the client socket, and the socket is only responsible for receiving client connection requests. The last socket received communicates with the client socket.
What are the main differences between synchronous and asynchronous?
The Accept receive is a blocking method, and the thread usually blocks when it executes here. Then the code behind them cannot be executed, and the Async method of Accept receive allows you to perform their subsequent processing. To give a simple example, if the client is receiving a piece of data, the data is longer, it takes 10 seconds, then the code after receive we want to execute immediately, do not need to wait to receive the completion of execution, this time the asynchronous receive will play a role, but there is still a misunderstanding, Will asynchrony increase concurrency? Not, async just acts as a non-blocking thread (async itself also opens up a new thread to wait for the data to be processed) and does not increase the ability to receive data concurrently. Concurrency processing is ultimately controlled by the thread, even if it is synchronous processing, we open up multiple threads for the same socket to receive operations, can still play a concurrent effect.
Private voidConnecttoserver () {//Create a socketIPEndPoint Ipep =NewIPEndPoint (Ipaddress.parse ("127.0.0.1"),6001); Clientsocket=Newsockets (AddressFamily.InterNetwork, SocketType.Stream, protocoltype.tcp); //connect the socket to the remote server address Try { //Client ConnectionsClientsocket.connect (IPEP); } Catch(SocketException ex) {MessageBox.Show ("Connect Error:"+Ex. Message); return; } for(inti =0; I <=3; i++) {Thread th=NewThread (NewThreadStart (Receive)); Th. IsBackground=true; Th. Start (); } } Public voidReceive () {byte[] data =New byte[1024x768]; while(true) { //Receiving server information intBuflen =0; Try { if(clientsocket.connected) {Buflen=clientsocket.receive (data); if(Buflen = =0) { Break; } } } Catch(Exception ex) {MessageBox.Show ("Receive Error:"+Ex. Message); return; } stringClientcommand = System.Text.Encoding.UTF8.GetString (data,0, Buflen);//. Substring (0, Buflen);Settextvalue (Clientcommand+Thread.CurrentThread.ManagedThreadId.ToString ()); } }
The above code is the client receives data processing process, opened up 4 threads for the same socket to do concurrent receive data capacity.
Next look at how asynchronous receive data is implemented
Private voidConnecttoserver () {byte[] data =New byte[1024x768]; //Create a socketIPEndPoint Ipep =NewIPEndPoint (Ipaddress.parse ("127.0.0.1"),6001); Clientsocket=Newsockets (AddressFamily.InterNetwork, SocketType.Stream, protocoltype.tcp); //connect the socket to the remote server address Try { //Client ConnectionsClientsocket.connect (IPEP); } Catch(SocketException ex) {MessageBox.Show ("Connect Error:"+Ex. Message); return; } if(clientsocket.connected) {clientsocket.beginreceive (buffer,0, data. Length, Socketflags.none, Receive, Clientsocket); } } Static byte[] buffer =New byte[1024x768]; Public voidReceive (IAsyncResult ar) {Try { varSocket = ar. AsyncState asSocket; varBuflen =socket. EndReceive (AR); if(Buflen >0) { stringClientcommand = System.Text.Encoding.UTF8.GetString (buffer,0, Buflen);//. Substring (0, Buflen);Settextvalue (Clientcommand +Thread.CurrentThread.ManagedThreadId.ToString ()); Socket. BeginReceive (Buffer,0, buffer. Length, Socketflags.none,NewAsyncCallback (Receive), socket); } if(Buflen = =0) {Settextvalue (the socketshutdown"); } } Catch(Exception ex) {MessageBox.Show ("Receive Error:"+Ex. Message); } }
After testing, the thread that receives the data asynchronously is always the same thread, so async itself does not have the ability to handle concurrency unless multiple threads are opened to receive data asynchronously.
How do you implement such a scenario?
I don't want to have a machine that opens up multiple threads to receive a socket, but flexibly dynamically threads as needed, guaranteeing both concurrency and not wasting threads. What does the socket mechanism in C # do to this? A question worth thinking about.
Finally summarize the synchronous and asynchronous way
If we stand in the main thread angle, if we do the socket operation, send or receive, we do not want to block the main thread to create a bad experience, then the asynchronous and synchronization differences are very large. But if we open up new threads based on the main thread to do these synchronizations, the individual thinks that the difference between async and synchronization is not very large, perhaps just the way code is different, because async itself does not solve the concurrency problem raised above. (This is my personal point of view)
How do you do thread finalization and exception handling?
If we close a socket
The best way is to first shutdown both sides of the socket, notify the remote is communicating the socket, this time the remote socket will be empty, if in the loop, you can break the end thread, if it is asynchronous, you can avoid the asynchronous call again, you can avoid catching unnecessary exceptions, However, it is still necessary to add exception handling mechanisms. Because if we close a socket directly, the remote socket's receive will catch the exception
if (clientsocket.connected) { Clientsocket.shutdown (socketshutdown.both); Clientsocket.close (); }
Server can cache client sockets?
If you implement complex communication requirements, multiple clients, clients are forwarded through the service side, so the server will not be able to do the forwarding function if they do not cache these client sockets. So when the client connection can bring their own flag information, server cache these sockets, according to the flag to remove the socket for forwarding, which is the realization of communication software ideas. But at the same time to do a good job of these client sockets management operations, interrupts, exceptions, shutdown and other timely cleanup.
How to realize the synchronous implementation of socket communication in C # and how to implement it asynchronously