I watched the <restructuring manual> for a while at home on May 1 and tried to improve it with the code I had previously written. I remembered the LAN chat tool that I wrote last summer. Now I can see that the code I wrote was unsightly, the most incredible thing is that the "multi-thread" method is used to process network requests. Now I think the asynchronous method should be used.
Main Design
Brief Description
The left part indicates the client process, and the right part indicates the server process. the client has fewer steps than the server before establishing a connection. After a successful connection is established, both the client and the server have a CommunicateSocket to communicate with the other Party, such as sending, receiving, and sending a file, receiving files.
Server, Declare ServerSocket, Bind an IP address and specify the communication port of this IP address, for example 127.0.0.1: 9050, ServerSocket can Listen to connection requests sent from multiple IP addresses, Listen (Listen) you can set the maximum number of allowed connection requests. then, call the BeginAccept method. If a client sends a connection request, a new CommunicateSocket is defined to communicate with the client. then you can use CommunicateSocket. the BeginSend () method sends data to the client, CommunicateSocket. beginReceive () can receive data from the client.
Client, There is a CommunicateSocket, and bound to an IP address and an unused port, define IPEndPoint serverIP to indicate the IP address and port of the server Socket, In order to communicate between ports, next, you can try CommunicateSocket. beginConnect (serverIP), after the connection is successful, you can send and receive data, CommunicateSocket. beginSend (), CommunicateSocket. beginReceive ().
Some asynchronous methods have two implementation methods, such as BeginAccept () and AcceptAsync (). What are the differences between these two methods?The method starting with Begin and End is implemented asynchronously using the APM (Asynchronous Programming Model) design method. The method ending with Async is called EAP (Event-based Asynchronous Pattern) the Asynchronous Operation implemented by the design method.
Code Part 1. SocketFunc class
SocketFunc is an abstract class. The method for establishing a connection between the server and the client is different. The other classes are the same. Therefore, put the same part in this class.
12345678910111213141516171819202122232425262728293031323334353637 |
public abstract class SocketFunc {
// Whether it is a server or a client, establish a connection and use this Socket for communication
public Socket communicateSocket = null ;
// The method for establishing a connection between the server and the client is slightly different, And the subclass will overload
public abstract void Access( string IP, System.Action AccessAciton);
// Message sending Function
public void Send( string message)
{
if (communicateSocket.Connected == false )
{
throw new Exception( "No connection has been established and messages cannot be sent" );
}
Byte[] msg = Encoding.UTF8.GetBytes(message);
communicateSocket.BeginSend(msg,0, msg.Length, SocketFlags.None,
ar => {
}, null );
}
// Message receiving function
public void Receive(System.Action< string > ReceiveAction)
{
// If the message contains more than 1024 bytes, the received message is divided into (total byte length/1024 + 1) lines.
Byte[] msg = new byte [1024];
// Asynchronous message receiving
communicateSocket.BeginReceive(msg, 0, msg.Length, SocketFlags.None,
ar => {
// When the other party disconnects, a Socket Exception is thrown here.
//An existing connection was forcibly closed by the remote host
communicateSocket.EndReceive(ar);
ReceiveAction(Encoding.UTF8.GetString(msg).Trim( '\0' , ' ' ));
Receive(ReceiveAction);
}, null );
} } |
2. ServerSocket: SocketFunc class
Inherited from the SocketFunc class. The Access method is overloaded in the class.
12345678910111213141516171819 |
public class ServerSocket:SocketFunc {
// The Access function is reloaded on the server.
public override void Access( string IP, System.Action AccessAciton)
{
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// IP address and port pre-used by the Local Machine
IPEndPoint serverIP = new IPEndPoint(IPAddress.Any, 9050);
// Bind the IP address set by the server
serverSocket.Bind(serverIP);
// Set the number of listeners
serverSocket.Listen(1);
// Receives connection requests asynchronously.
serverSocket.BeginAccept(ar =>
{
base .communicateSocket = serverSocket.EndAccept(ar);
AccessAciton();
}, null );
} } |
3. ClientSocket: SocketFunc class
Inherited from the SocketFunc class. The Access method is overloaded in the class.
1234567891011121314151617181920212223242526272829303132 |
public class ClientSocket:SocketFunc {
// The Access function is reloaded on the client.
public override void Access( string IP, System.Action AccessAciton)
{
base .communicateSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
base .communicateSocket.Bind( new IPEndPoint(IPAddress.Any, 9051));
// Server IP address and port
IPEndPoint serverIP;
try
{
serverIP = new IPEndPoint(IPAddress.Parse(IP), 9050);
}
catch
{
throw new Exception(String.Format( "{0} is not a valid IP address! " , IP));
}
// The client is only used to send information to the specified server. You do not need to bind the local IP address and port, and do not need to listen.
try
{
base .communicateSocket.BeginConnect(serverIP, ar =>
{
AccessAciton();
}, null );
}
catch
{
throw new Exception( string .Format( "Failed to connect {0! " , IP));
}
} } |
Program
Source code download
Http://www.cnblogs.com/technology/archive/2011/05/03/2035410.html