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 Huang _ server
{
public partial class Form1:form
{
Public Form1 ()
{
InitializeComponent ();
}
<summary>
Server listens to Client connection thread
</summary>
Thread threadwatchs = null;
<summary>
Server sockets
</summary>
Socket socketserver = null;
<summary>
The server monitors the client connection condition of the thread
</summary>
Thread monitothread = null;
<summary>
A collection of client IP and sockets
</summary>
dictionary<string, socket> dictsocket = new dictionary<string, socket> ();
<summary>
A collection of client IP and threads
</summary>
dictionary<string, thread> dictthread = new dictionary<string, thread> ();
<summary>
The number of client connection threads
</summary>
Long numthreadval = 0;
<summary>
Server IP
</summary>
String strServerIP = "192.168.4.3";
<summary>
Server port
</summary>
int serverport = 8080;
<summary>
Cache data Length
</summary>
int receivedatavallengt = 1024;//buffer length
<summary>
For pinging clients
</summary>
Ping monitoping = new Ping ();
<summary>
An abnormally fractured client
</summary>
dictionary<string, string> dictbodclient = new dictionary<string, string> ();
<summary>
Indicates free release thread
</summary>
BOOL Isclearthread = false;
ULONG Numdataflow;
private void Form1_Load (object sender, EventArgs e)
{
Turn on the server
OpenServer (strServerIP, ServerPort);
Turn on the server monitoring thread
Monitothread = new Thread (monitothreadsdynamic);
Background thread
Monitothread.isbackground = true;
Start thread
Monitothread.start ();
}
<summary>
Start monitoring client connections in real time
</summary>
void Monitothreadsdynamic ()
{
Delegateshowmseeage ("Start real-time monitoring of client connections");
while (true)
{
Thread.Sleep (3000);
Try
{
foreach (var vv in dictsocket)
{
pingreply reply = Monitoping.send (vv. Key.split (': ') [0],1000];
If the ping Pass
if (reply. Status = = ipstatus.success)
{
Indicates that the client connection is healthy
Delegateshowmseeage ("Client" + VV.) Key + "Connection OK");
}
Else
{
Delegateshowmseeage ("Client" + VV.) Key + "Connection exception");
Add exception client connects to collection Dictbodclient
Dictbodclient.add (vv. Key, "old");
}
}
Release the thread of the exception connection
foreach (Var vvv in Dictthread)
{
Isclearthread = false;
foreach (Var vvvv in dictbodclient)
{
if (VVV. Key = = VVVV. Key)
{
Isclearthread = true;
Break
}
}
if (Isclearthread)
{
Vvv. Value.abort ();
Delegateshowmseeage ("Client" + VVV. Key + "Thread Occupied" is released);
}
}
Remove the client for the exception connection from the collection close
foreach (Var vvv in dictbodclient)
{
Remove a client socket from the collection
Dictsocket.remove (VVV. Key);
To remove a client thread from the collection
Dictthread.remove (VVV. Key);
To remove a remote endpoint for a 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 ();
Gets the total number of threads currently running in the program
Numthreadval = Process.getcurrentprocess (). Threads.count;
Delegateshowmseeage ("The total number of current threads is:" + numthreadval);
The number of threads that are used to obtain client connections
Numthreadval = Dictthread.longcount ();
displaying messages across threads
Delegateshowmseeage ("The number of threads where the client is connected:" + numthreadval);
}
}
//<summary>
//Open Server
//</summary>
//<param name= "ServerIP" ></PARAM>
/ <param name= "ServerPort" ></PARAM>
void OpenServer (string serverip, int serverport)
{
// Instantiate the 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 connection parameters for server sockets
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, specifying the maximum number of clients is 10000
Socketserver.listen (10000);
//instantiating the server listening to a client-connected thread
Threadwatchs = new Thread (watchclientconnecting);
//Background running thread
Threadwatchs.isbackground = true;
//Boot thread
Threadwatchs.start ();
//Display prompt message
Showmesssge ( "Server started successfully");
}
<summary>
Start listening to the client
</summary>
void Watchclientconnecting ()
{
Display prompt messages across threads
Delegateshowmseeage ("Server starts listening to client connections");
while (true)
{
Listen to new Client connection requests
Socket newclientconnecting = socketserver.accept ();
Add a remote endpoint to a list of client sockets
Addclientsocket (NewClientConnecting.RemoteEndPoint.ToString ());
Create a new client thread
Thread newclinetthread = new Thread (receivedata);
Running the client in the background
Newclinetthread.isbackground = true;
Starts the thread and binds the new client's socket to the method that the thread executes
Newclinetthread.start (newclientconnecting);
To add a client socket to a collection
Dictsocket.add (NewClientConnecting.RemoteEndPoint.ToString (), newclientconnecting);
Add a thread to the collection where the client accepts data
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)
{
Gets the thread-bound client socket
Socket socketclient = socketconnecting as socket;
while (true)
{
Create a new buffer
byte[] Receivedataval = new Byte[receivedatavallengt];
Data length
int receivedatalength =-1;
Try
{
Accept data to fill in buffers and get data length
Receivedatalength = Socketclient.receive (receivedataval);
Receive data
if (Receivedatalength > 0)
{
To display the received data across threads
Delegateshowreceivedata (Socketclient, Receivedataval, receivedatalength);
Integrated processing of received data
Receivedataintegratedprocessing (Receivedataval, receivedatalength);
Numdataflow + = (UINT) receivedatalength;
Showdataflow ();
}
Else
{
Remove a client socket from the collection
Dictsocket.remove (SocketClient.RemoteEndPoint.ToString ());
To remove a client thread from the collection
Dictthread.remove (SocketClient.RemoteEndPoint.ToString ());
To remove a remote endpoint for a client socket from the list
Deleteclientsocket (SocketClient.RemoteEndPoint.ToString ());
Display prompt data across threads
Delegateshowmseeage ("Client" + socketClient.RemoteEndPoint.ToString () + "Disconnected");
Release the thread
Return
}
}
Catch
{
Remove a client socket from the collection
Dictsocket.remove (SocketClient.RemoteEndPoint.ToString ());
To remove a client thread from the collection
Dictthread.remove (SocketClient.RemoteEndPoint.ToString ());
To remove a remote endpoint for a 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>
Integrated processing of 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 accepted data to all clients
//*******************************************************************
Iterating through a collection 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 prompt messages across threads
Delegateshowmseeage ("New thread ready to start sending data");
New parameter model for sending data
Datasendargsmode Senddataargs = new Datasendargsmode ();
Bind a client socket to a model
Senddataargs.sockets = Clientsocket;
Binding data to a model
Senddataargs.datas = datas;
Binding data lengths to models
senddataargs.length = length;
Create a new thread to send data to the client
Thread threadsenddatatoclient = new Thread (senddatatoclient);
Running threads in the background
Threadsenddatatoclient.isbackground = true;
The thread is started and the parameter model that sends the data is bound to the method that the thread executes
Threadsenddatatoclient.start (Senddataargs);
}
<summary>
Sending data to the client
</summary>
<param name= "obj" ></param>
void Senddatatoclient (Object obj)
{
Get the parameter model for sending data
Datasendargsmode args = obj as Datasendargsmode;
Try
{
Extracting data from the data parameter model to clients in the model
Args.sockets.Send (Args.datas, 0, Args.length, socketflags.none);
Display prompt messages across threads
Delegateshowmseeage ("Data:" + getstringformbyte (Args.datas, args.length) + "sent to the client:" + Args.sockets.RemoteEndPoint.ToString ());
Delegateshowmseeage ("Data sent, close thread");
Release the thread
Numdataflow + = (UINT) args.length;
Showdataflow ();
Return
}
Catch
{
Remove a client socket from the collection
Dictsocket.remove (Args.sockets.RemoteEndPoint.ToString ());
To remove a client thread from the collection
Dictthread.remove (Args.sockets.RemoteEndPoint.ToString ());
To remove a remote endpoint for a client socket from the list
Deleteclientsocket (Args.sockets.RemoteEndPoint.ToString ());
Display prompt messages across threads
Delegateshowmseeage ("Exception:" + "client" + args.sockets.RemoteEndPoint.ToString () + "disconnect" + "close the thread");
Release the thread
Return
}
}
<summary>
Remove a client from the list
</summary>
<param name= "Socket" ></param>
void Deleteclientsocket (String strclientsocket)
{
Encapsulates a method for delegation
Action<string> actiondelegate = (x) = =
{
Remove the remote endpoint for the specified client socket from the list
LbOnlineClient.Items.Remove (X.tostring ());
};
Delegates a parameter to the specified method execution
Txtmessage.invoke (Actiondelegate, Strclientsocket);
}
<summary>
Add Client to List
</summary>
<param name= "Clientsocket" ></param>
void Addclientsocket (String strclientsocket)
{
Encapsulates a method for delegation
Action<string> actiondelegate = (x) = =
{
To add a remote endpoint for the specified client socket to the list
LBONLINECLIENT.ITEMS.ADD (X.tostring ());
};
Delegates a parameter to the specified method execution
Txtmessage.invoke (Actiondelegate, Strclientsocket);
}
//<summary>
//cross-thread display of received data
//</SUMMARY>
//<param name= "socket" ></param>< br>//<param name= "Datas" ></PARAM>
//<param name= "Length" ></PARAM>
Void Delegateshowreceivedata (socket socket, byte[] datas, int length)
{
//encapsulates 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 ();
}; The
//delegate parameter to the specified method execution
Txtmessage.invoke (Actiondelegate, "received from" + socket. Remoteendpoint.tostring () + "data:" + getstringformbyte (datas, length));
}
<summary>
Displaying data across threads
</summary>
<param name= "Message" ></param>
void Delegateshowmseeage (String message)
{
Encapsulates a method for delegation
Action<string> actiondelegate = (x) = =
{
if (TxtMessage.Text.Length > 2000000)
Txtmessage.text = string. Empty;
Append text to a text box
Txtmessage.appendtext (System.DateTime.Now.ToString () + "+" + x.tostring () + "\ r \ n");
Txtmessage.scrolltocaret ();
};
Delegates a parameter to the specified method execution
Txtmessage.invoke (actiondelegate, message);
}
<summary>
Show Data traffic
</summary>
void Showdataflow ()
{
Encapsulates a method for delegation
Action<string> Actiondelegateshowflow = (x) = =
{
Lbldataflow.text = X.tostring ();
};
Delegates a parameter to the specified method execution
Lbldataflow.invoke (Actiondelegateshowflow, numdataflow.tostring ());
}
<summary>
Show data
</summary>
<param name= "Message" ></param>
void Showmesssge (String message)
{
Append text to a text box
Txtmessage.appendtext (System.DateTime.Now.ToString () + "+" + message + "\ r \ n");
Txtmessage.scrolltocaret ();
}
<summary>
16 Binary string form
</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>
Sockets
</summary>
public Socket sockets;
<summary>
Data
</summary>
Public byte[] Datas;
<summary>
Length
</summary>
public int length;
}
}
C#TCP Multithreaded Server Instance code