C # tcp multi-thread server instance code,
Using System;
Using System. Collections. Generic;
Using System. ComponentModel;
Using System. Data;
Using System. Drawing;
Using System. Linq;
Using System. Text;
Using System. Threading. Tasks;
Using System. Windows. Forms;
Using System. Net;
Using System. Net. Sockets;
Using System. Threading;
Using System. Diagnostics;
Using System. Net. NetworkInformation;
Namespace Huang Yanpei _ Server
{
Public partial class Form1: Form
{
Public Form1 ()
{
InitializeComponent ();
}
/// <Summary>
/// The server listens to the client connection thread
/// </Summary>
Thread threadWatchs = null;
/// <Summary>
/// Server socket
/// </Summary>
Socket socketServer = null;
/// <Summary>
/// The thread in which the server monitors the Client Connection
/// </Summary>
Thread MonitoThread = null;
/// <Summary>
/// Set of Client ip addresses and sockets
/// </Summary>
Dictionary <string, Socket> dictSocket = new Dictionary <string, Socket> ();
/// <Summary>
/// Set of Client ip addresses and threads
/// </Summary>
Dictionary <string, Thread> dictThread = new Dictionary <string, Thread> ();
/// <Summary>
/// Number of client connection threads
/// </Summary>
Long numThreadVal = 0;
/// <Summary>
/// Server ip Address
/// </Summary>
String strServerIP = "192.168.4.3 ";
/// <Summary>
/// Server port
/// </Summary>
Int serverPort = 8080;
/// <Summary>
/// Cache Data Length
/// </Summary>
Int receiveDataValLengt = 1024; // cache Zone Length
/// <Summary>
/// Ping the client
/// </Summary>
Ping monitoPing = new Ping ();
/// <Summary>
/// Client with an exception or disconnection
/// </Summary>
Dictionary <string, string> dictBodClient = new Dictionary <string, string> ();
/// <Summary>
/// Indicates releasing the release thread
/// </Summary>
Bool isclearthur READ = false;
Ulong numDataFlow;
Private void Form1_Load (object sender, EventArgs e)
{
// Enable the server
OpenServer (strServerIP, serverPort );
// Enable the server monitoring thread
MonitoThread = new Thread (monitoThreadsDynamic );
// Background thread
MonitoThread. IsBackground = true;
// Start the thread
MonitoThread. Start ();
}
/// <Summary>
/// Start monitoring the client connection in real time
/// </Summary>
Void monitoThreadsDynamic ()
{
DelegateShowMseeage ("start to Monitor client connection status in Real Time ");
While (true)
{
Thread. Sleep (3000 );
Try
{
Foreach (var vv in dictSocket)
{
PingReply reply = monitoPing. Send (vv. Key. Split (':') [0], 1000 );
// If Ping succeeds
If (reply. Status = IPStatus. Success)
{
// Indicates that the client connection is normal.
DelegateShowMseeage ("client" + vv. Key + "connection normal ");
}
Else
{
DelegateShowMseeage ("client" + vv. Key + "connection exception ");
// Add an abnormal client to connect to the set dictBodClient
DictBodClient. Add (vv. Key, "old ");
}
}
// Release the abnormal connection thread
Foreach (var vvv in dictThread)
{
Isclearthur READ = false;
Foreach (var vvvv in dictBodClient)
{
If (vvv. Key = vvvv. Key)
{
Isclearthur READ = true;
Break;
}
}
If (isclearthur read)
{
Vvv. Value. Abort ();
DelegateShowMseeage ("client" + vvv. Key + "the occupied thread has been released ");
}
}
// Remove the client with abnormal connection from the collection
Foreach (var vvv in dictBodClient)
{
// Remove the client socket from the set
DictSocket. Remove (vvv. Key );
// Remove the client thread from the set
DictThread. Remove (vvv. Key );
// Remove the remote endpoint of the client socket from the list
DeleteClientSocket (vvv. Key );
// Display prompt data across threads
DelegateShowMseeage ("client" + vvv. Key + "Disconnect ");
}
}
Catch (Exception se)
{
// MessageBox. Show (se. Message );
DelegateShowMseeage (se. Message );
}
DictBodClient. Clear ();
// Obtain the total number of threads currently running
NumThreadVal = Process. GetCurrentProcess (). Threads. Count;
DelegateShowMseeage ("Total number of threads currently:" + numThreadVal );
// Obtain the number of threads used by client connections
NumThreadVal = dictThread. LongCount ();
// Display messages across threads
DelegateShowMseeage ("the number of threads connected to the client is:" + numThreadVal );
}
}
/// <Summary>
/// Enable the server
/// </Summary>
/// <Param name = "serverIP"> </param>
/// <Param name = "serverPort"> </param>
Void openServer (string serverIP, int serverPort)
{
// Instantiate a server socket
SocketServer = new Socket (AddressFamily. InterNetwork, SocketType. Stream, ProtocolType. Tcp );
// Configure the network endpoint
IPEndPoint ipAndPort = new IPEndPoint (IPAddress. Parse (serverIP), serverPort );
Try
{
// Set the connection parameters of the server socket
SocketServer. SetSocketOption (SocketOptionLevel. Socket, SocketOptionName. ReuseAddress, true );
// Bind the network endpoint to the server socket
SocketServer. Bind (ipAndPort );
}
Catch (SocketException se)
{
MessageBox. Show ("exception:" + se. Message );
Return;
}
// The server starts listening. The maximum number of clients allowed is 10000.
SocketServer. Listen (10000 );
// Instantiate the server to listen to the client connection thread
ThreadWatchs = new Thread (WatchClientConnecting );
// Background running thread
ThreadWatchs. IsBackground = true;
// Start the thread
ThreadWatchs. Start ();
// Display the prompt message
ShowMesssge ("server started successfully ");
}
/// <Summary>
/// Start listening to the client
/// </Summary>
Void WatchClientConnecting ()
{
// Display the prompt message across threads
DelegateShowMseeage ("the server starts to listen to the Client Connection ");
While (true)
{
// Listen to new client connection requests
Socket newClientConnecting = socketServer. Accept ();
// Add the remote endpoint list of the client socket
AddClientSocket (newClientConnecting. RemoteEndPoint. ToString ());
// Create a new client thread
Thread newClinetThread = new Thread (receiveData );
// Run the client in the background
NewClinetThread. IsBackground = true;
// Start the thread and bind the socket of the new client to the method of thread execution
NewClinetThread. Start (newClientConnecting );
// Add client socket to the set
DictSocket. Add (newClientConnecting. RemoteEndPoint. ToString (), newClientConnecting );
// Add the thread from which the client receives data to the set
DictThread. Add (newClientConnecting. RemoteEndPoint. ToString (), newClinetThread );
// Display prompt information across threads
DelegateShowMseeage ("new client:" + newClientConnecting. RemoteEndPoint. ToString ());
}
}
/// <Summary>
/// Accept data
/// </Summary>
/// <Param name = "socketConnecting"> </param>
Void receiveData (object socketConnecting)
{
// Obtain the client socket bound to this thread
Socket socketClient = socketConnecting as Socket;
While (true)
{
// Create a cache area
Byte [] receiveDataVal = new byte [receiveDataValLengt];
// Data Length
Int receiveDataLength =-1;
Try
{
// Accept data and enter it in the cache and obtain the Data Length
ReceiveDataLength = socketClient. Receive (receiveDataVal );
// Receive data
If (receiveDataLength> 0)
{
// Display received data across threads
DelegateShowReceiveData (socketClient, receiveDataVal, receiveDataLength );
// Comprehensively process received data
ReceiveDataIntegratedProcessing (receiveDataVal, receiveDataLength );
NumDataFlow + = (uint) receiveDataLength;
ShowDataFlow ();
}
Else
{
// Remove the client socket from the set
DictSocket. Remove (socketClient. RemoteEndPoint. ToString ());
// Remove the client thread from the set
DictThread. Remove (socketClient. RemoteEndPoint. ToString ());
// Remove the remote endpoint of the client socket from the list
DeleteClientSocket (socketClient. RemoteEndPoint. ToString ());
// Display prompt data across threads
DelegateShowMseeage ("client" + socketClient. RemoteEndPoint. ToString () + "Disconnect ");
// Release the thread
Return;
}
}
Catch
{
// Remove the client socket from the set
DictSocket. Remove (socketClient. RemoteEndPoint. ToString ());
// Remove the client thread from the set
DictThread. Remove (socketClient. RemoteEndPoint. ToString ());
// Remove the remote endpoint of the client socket from the list
DeleteClientSocket (socketClient. RemoteEndPoint. ToString ());
// Display prompt data across threads
DelegateShowMseeage ("exception:" + "client" + socketClient. RemoteEndPoint. ToString () + "Disconnect ");
// Release the thread
Return;
}
}
}
/// <Summary>
/// Comprehensively process received data
/// </Summary>
/// <Param name = "datas"> </param>
/// <Param name = "length"> </param>
Void receiveDataIntegratedProcessing (byte [] datas, int length)
{
// If (length = 5)
//{
// If (datas [0] = 0x11 & datas [4] = 0x11)
//{
// Foreach (var clients in dictSocket)
//{
// NewOneThreadSendDataToClient (clients. Value, datas, length );
//}
//}
// Else if (datas [0] = 0x12 & datas [4] = 0x12)
//{
// Foreach (var clients in dictSocket)
//{
// NewOneThreadSendDataToClient (clients. Value, datas, length );
//}
//}
//}
//************************************** *****************************
// Send the received data to all clients
//************************************** *****************************
// Traverses the set of client sockets
Foreach (var clients in dictSocket)
{
// Create a new thread to send data to the client
NewOneThreadSendDataToClient (clients. Value, datas, length );
}
}
Void newOneThreadSendDataToClient (Socket clientSocket, byte [] datas, int length)
{
// Display the prompt message across threads
DelegateShowMseeage ("Creating a New thread to start sending data ");
// Create a parameter model for sending data
DataSendArgsMode sendDataArgs = new dataSendArgsMode ();
// Bind the client socket to the model
SendDataArgs. sockets = clientSocket;
// Bind data to the model
SendDataArgs. datas = datas;
// Bind the data length to the model
SendDataArgs. length = length;
// Create a thread for sending data to the client
Thread threadSendDataToClient = new Thread (sendDataToClient );
// Background running thread
ThreadSendDataToClient. IsBackground = true;
// Start the thread and bind the parameter model of the sent data to the method of thread execution
ThreadSendDataToClient. Start (sendDataArgs );
}
/// <Summary>
/// Send data to the client
/// </Summary>
/// <Param name = "obj"> </param>
Void sendDataToClient (object obj)
{
// Obtain the parameter model used to send data
DataSendArgsMode args = obj as dataSendArgsMode;
Try
{
// Extract data from the data parameter model and send it to the client in the Model
Args. sockets. Send (args. datas, 0, args. length, SocketFlags. None );
// Display the prompt message across threads
DelegateShowMseeage ("data:" + getStringFormByte (args. datas, args. length) + "sent to client:" + args. sockets. RemoteEndPoint. ToString ());
DelegateShowMseeage ("Data Transmission completed, thread disabled ");
// Release the thread
NumDataFlow + = (uint) args. length;
ShowDataFlow ();
Return;
}
Catch
{
// Remove the client socket from the set
DictSocket. Remove (args. sockets. RemoteEndPoint. ToString ());
// Remove the client thread from the set
DictThread. Remove (args. sockets. RemoteEndPoint. ToString ());
// Remove the remote endpoint of the client socket from the list
DeleteClientSocket (args. sockets. RemoteEndPoint. ToString ());
// Display the prompt message across threads
DelegateShowMseeage ("exception:" + "client" + args. sockets. RemoteEndPoint. ToString () + "Disconnect" + ", close this thread ");
// Release the thread
Return;
}
}
/// <Summary>
/// Delete the client from the list
/// </Summary>
/// <Param name = "socket"> </param>
Void deleteClientSocket (string strClientSocket)
{
// Encapsulate a method for Delegation
Action <string> actionDelegate = (x) =>
{
// Remove the remote endpoint of the specified client socket from the list
LbOnlineClient. Items. Remove (x. ToString ());
};
// Delegate the parameter to the specified method for execution
TxtMessage. Invoke (actionDelegate, strClientSocket );
}
/// <Summary>
/// Add the client to the list
/// </Summary>
/// <Param name = "clientSocket"> </param>
Void addClientSocket (string strClientSocket)
{
// Encapsulate a method for Delegation
Action <string> actionDelegate = (x) =>
{
// Add the remote endpoint of the specified client socket to the list
LbOnlineClient. Items. Add (x. ToString ());
};
// Delegate the parameter to the specified method for execution
TxtMessage. Invoke (actionDelegate, strClientSocket );
}
/// <Summary>
/// Display received data across threads
/// </Summary>
/// <Param name = "socket"> </param>
/// <Param name = "datas"> </param>
/// <Param name = "length"> </param>
Void delegateShowReceiveData (Socket socket, Byte [] datas, int length)
{
// Encapsulate a method for Delegation
Action <string> actionDelegate = (x) =>
{
// Append text to the text box
TxtMessage. AppendText (System. DateTime. Now. ToString () + "->" + x. ToString () + "\ r \ n ");
TxtMessage. ScrollToCaret ();
};
// Delegate the parameter to the specified method for execution
TxtMessage. Invoke (actionDelegate, "received data from" + socket. RemoteEndPoint. ToString () + ":" + getStringFormByte (datas, length ));
}
/// <Summary>
/// Display data across threads
/// </Summary>
/// <Param name = "message"> </param>
Void delegateShowMseeage (string message)
{
// Encapsulate a method for Delegation
Action <string> actionDelegate = (x) =>
{
If (txtMessage. Text. Length> 2000000)
TxtMessage. Text = string. Empty;
// Append text to the text box
TxtMessage. AppendText (System. DateTime. Now. ToString () + "->" + x. ToString () + "\ r \ n ");
TxtMessage. ScrollToCaret ();
};
// Delegate the parameter to the specified method for execution
TxtMessage. Invoke (actionDelegate, message );
}
/// <Summary>
/// Display data traffic
/// </Summary>
Void showDataFlow ()
{
// Encapsulate a method for Delegation
Action <string> actionDelegateShowFlow = (x) =>
{
LblDataFlow. Text = x. ToString ();
};
// Delegate the parameter to the specified method for execution
LblDataFlow. Invoke (actionDelegateShowFlow, numDataFlow. ToString ());
}
/// <Summary>
/// Display data
/// </Summary>
/// <Param name = "message"> </param>
Void showMesssge (string message)
{
// Append text to the text box
TxtMessage. AppendText (System. DateTime. Now. ToString () + "->" + message + "\ r \ n ");
TxtMessage. ScrollToCaret ();
}
/// <Summary>
/// Hexadecimal string format
/// </Summary>
/// <Param name = "data"> </param>
/// <Param name = "length"> </param>
/// <Returns> </returns>
String getStringFormByte (byte [] data, int length)
{
String str = "";
For (int I = 0; I <length; I ++)
{
Str + = data [I]. ToString ("X"). PadLeft (2, '0') + '';
}
Return str;
}
}
/// <Summary>
/// Parameters for sending data
/// </Summary>
Class dataSendArgsMode
{
/// <Summary>
/// Socket
/// </Summary>
Public Socket sockets;
/// <Summary>
/// Data
/// </Summary>
Public byte [] datas;
/// <Summary>
/// Length
/// </Summary>
Public int length;
}
}