Asynchronous ServerCode.
Code
Class Asynchronousioserver
{
Private Socket _ serversocket;
Private Int _ Port;
Public Asynchronousioserver ( Int Port_num)
{
_ Port = Port_num;
}
Private Class Connectioninfo
{
Public Socket socket;
Public Byte [] Buffer;
}
Private List < Connectioninfo > _ Connections =
New List < Connectioninfo > ();
Public Void Start ()
{
Setupserversocket ();
For ( Int I = 0 ; I < 10 ; I ++ )
_ Serversocket. beginaccept (
New Asynccallback (acceptcallback), _ serversocket );
}
Private Void Setupserversocket ()
{
Iphostentry localmachineinfo =
DNS. gethostentry (DNS. gethostname ());
Ipendpoint myendpoint = New Ipendpoint (
Localmachineinfo. Addresslist [ 0 ], _ Port );
_ Serversocket = New Socket (myendpoint. Address. addressfamily,
Sockettype. Stream, protocoltype. TCP );
_ Serversocket. BIND (myendpoint );
_ Serversocket. Listen (( Int ) Socketoptionname. maxconnections );
}
Private Void Acceptcallback (iasyncresult result)
{
Connectioninfo connection = New Connectioninfo ();
Try
{
Socket s = (Socket) result. asyncstate;
Connection. Socket = S. endaccept (result );
Connection. Buffer = New Byte [ 255 ];
Lock (_ Connections) _ connections. Add (connection );
Connection. Socket. beginreceive (connection. buffer, 0 ,
Connection. Buffer. length, socketflags. None,
New Asynccallback (receivecallback), connection );
_ Serversocket. beginaccept ( New Asynccallback (acceptcallback ),
Result. asyncstate );
}
Catch (Socketexception exc)
{
Closeconnection (connection );
Console. writeline ( " Socket exception: " + Exc. socketerrorcode );
}
Catch (Exception exc)
{
Closeconnection (connection );
Console. writeline ( " Exception: " + Exc );
}
}
Private Void Effececallback (iasyncresult result)
{
Connectioninfo connection = (Connectioninfo) result. asyncstate;
Try
{
Int Bytesread = Connection. Socket. endreceive (result );
If ( 0 ! = Bytesread)
{
Lock (_ Connections)
{
Foreach (Connectioninfo Conn In _ Connections)
{
If (Connection ! = Conn)
{
Conn. Socket. Send (connection. buffer, bytesread,
Socketflags. None );
}
}
}
Connection. Socket. beginreceive (connection. buffer, 0 ,
Connection. Buffer. length, socketflags. None,
New Asynccallback (receivecallback), connection );
}
Else Closeconnection (connection );
}
Catch (Socketexception exc)
{
Closeconnection (connection );
Console. writeline ( " Socket exception: " + Exc. socketerrorcode );
}
Catch (Exception exc)
{
Closeconnection (connection );
Console. writeline ( " Exception: " + Exc );
}
}
Private Void Closeconnection (connectioninfo CI)
{
CI. Socket. Close ();
Lock (_ Connections) _ connections. Remove (CI );
}
}
Socket ClientProgram
The server has been responsive and carries a large volume of data. Now an efficient client program is needed. In comparison, this is relatively simple. In the client program, you must first construct a socket. You can choose to bind the socket to a specific address and port. If there is no binding, the network layer will provide an address that it deems best to bind with it and a specific port, the port number is between 1024 and 5000.
The reason why you need to bind the socket of the client program to a certain address and port is that on a computer terminal with multiple NICs, and the address of each Nic is different, in this case, you can select the NIC to be used by the client.
Next we will use socket to connect to the server. The connection can also be synchronized or asynchronous. Asynchronous is a useful method when you need to connect to multiple servers. Each socket does not have to wait until the previous socket connection is established. The program can start multiple connections at the same time.
Even if the server is available, the wsaeconnrefused error may still occur when the client is connected, which may occur when the server Queue is full. In this case, the client needs to try to reconnect each time.
More improvements
The first aspect is to receive connections. There are three methods to basically accept asynchronous connections: only receive connections, receive connections, and receive the first few bytes of data sent by connections, use a special socket to receive the first few bytes of data sent by the connection .. Net Framework 1.x can only use the first method. In. net2.0, all three methods can be used.
The first Asynchronous Method Used by the previous server code. The advantage of only receiving connections is that the receiving logic and message processing logic can be isolated. This is a very simple programming model, but it does not provide the best performance.
The advantage of the method for receiving connections and receiving data is the significant improvement in the performance of the first message processing, mainly because the core processing program is basically not required to be called. This method is good when a specific protocol is used and the protocol header is known. The bad thing is that only the processing function of beginaccept is called after the data is accepted, which may produce connections that are unknown to some programs. This method is advantageous in combination with the socket. Disconnect method in. net2.0. In the previous socket program, if the socket cannot be used, you need to disable and delete the instance. With the socket. Disconnect method, you can reuse the instance, which is implemented through a socket instance pool of the program itself. Using this control in some solutions will greatly improve the performance.
When running the program, first tell the operating system to listen to the connection, and it will keep a connection queue of a specific length. Assuming that the maximum number is 200, it means that if more than 200 clients are connected at the same time, clients outside the queue will encounter a wsaeconnrefused error due to server rejection. One solution to this problem is to use multiple receivers for processing. By using this method, you can continuously receive and process connections from the queued connections, even if the connection being processed is not yet submitted to receive requests. This greatly increases the thickness of the listening queue.
However, multiple asynchronous operations are costly. The increase in connection processing will lead to a reduction in performance, and the increase in carrying capacity will also be at the cost of performance reduction.