這篇文章將為大家詳細講解有關C#使用Socket實現服務器與多個客戶端通信的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
擴展:
由于server端是存儲了所有server與client的連接對象,因此我們是可以基于此demo的基礎上實現聊天系統:
* 每當一個與用戶發言時,是由server接收到的某個用戶的發言信息的,此時服務器端可以通過循環發送該用戶發送的信息給每個已經連接連接的用戶(排除發送者)。
Server端代碼:
class Program
{
//創建一個和客戶端通信的套接字
static Socket SocketWatch = null;
//定義一個集合,存儲客戶端信息
static Dictionary<string, Socket> ClientConnectionItems = new Dictionary<string, Socket> { };
static void Main(string[] args)
{
//端口號(用來監聽的)
int port = 6000;
//string host = "127.0.0.1";
//IPAddress ip = IPAddress.Parse(host);
IPAddress ip = IPAddress.Any;
//將IP地址和端口號綁定到網絡節點point上
IPEndPoint ipe = new IPEndPoint(ip, port);
//定義一個套接字用于監聽客戶端發來的消息,包含三個參數(IP4尋址協議,流式連接,Tcp協議)
SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//監聽綁定的網絡節點
SocketWatch.Bind(ipe);
//將套接字的監聽隊列長度限制為20
SocketWatch.Listen(20);
//負責監聽客戶端的線程:創建一個監聽線程
Thread threadwatch = new Thread(WatchConnecting);
//將窗體線程設置為與后臺同步,隨著主線程結束而結束
threadwatch.IsBackground = true;
//啟動線程
threadwatch.Start();
Console.WriteLine("開啟監聽......");
Console.WriteLine("點擊輸入任意數據回車退出程序......");
Console.ReadKey();
SocketWatch.Close();
//Socket serverSocket = null;
//int i=1;
//while (true)
//{
// //receive message
// serverSocket = SocketWatch.Accept();
// Console.WriteLine("連接已經建立!");
// string recStr = "";
// byte[] recByte = new byte[4096];
// int bytes = serverSocket.Receive(recByte, recByte.Length, 0);
// //recStr += Encoding.ASCII.GetString(recByte, 0, bytes);
// recStr += Encoding.GetEncoding("utf-8").GetString(recByte, 0, bytes);
// //send message
// Console.WriteLine(recStr);
// Console.Write("請輸入內容:");
// string sendStr = Console.ReadLine();
// //byte[] sendByte = Encoding.ASCII.GetBytes(sendStr);
// byte[] sendByte = Encoding.GetEncoding("utf-8").GetBytes(sendStr);
// //Thread.Sleep(4000);
// serverSocket.Send(sendByte, sendByte.Length, 0);
// serverSocket.Close();
// if (i >= 100)
// {
// break;
// }
// i++;
//}
//sSocket.Close();
//Console.WriteLine("連接關閉!");
//Console.ReadLine();
}
//監聽客戶端發來的請求
static void WatchConnecting()
{
Socket connection = null;
//持續不斷監聽客戶端發來的請求
while (true)
{
try
{
connection = SocketWatch.Accept();
}
catch (Exception ex)
{
//提示套接字監聽異常
Console.WriteLine(ex.Message);
break;
}
//客戶端網絡結點號
string remoteEndPoint = connection.RemoteEndPoint.ToString();
//添加客戶端信息
ClientConnectionItems.Add(remoteEndPoint, connection);
//顯示與客戶端連接情況
Console.WriteLine("\r\n[客戶端\"" + remoteEndPoint + "\"建立連接成功! 客戶端數量:" + ClientConnectionItems .Count+ "]");
//獲取客戶端的IP和端口號
IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port;
//讓客戶顯示"連接成功的"的信息
string sendmsg = "[" + "本地IP:" + clientIP + " 本地端口:" + clientPort.ToString() + " 連接服務端成功!]";
byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg);
connection.Send(arrSendMsg);
//創建一個通信線程
Thread thread = new Thread(recv);
//設置為后臺線程,隨著主線程退出而退出
thread.IsBackground = true;
//啟動線程
thread.Start(connection);
}
}
/// <summary>
/// 接收客戶端發來的信息,客戶端套接字對象
/// </summary>
/// <param name="socketclientpara"></param>
static void recv(object socketclientpara)
{
Socket socketServer = socketclientpara as Socket;
while (true)
{
//創建一個內存緩沖區,其大小為1024*1024字節 即1M
byte[] arrServerRecMsg = new byte[1024 * 1024];
//將接收到的信息存入到內存緩沖區,并返回其字節數組的長度
try
{
int length = socketServer.Receive(arrServerRecMsg);
//將機器接受到的字節數組轉換為人可以讀懂的字符串
string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
//將發送的字符串信息附加到文本框txtMsg上
Console.WriteLine("\r\n[客戶端:" + socketServer.RemoteEndPoint + " 時間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")+ "]\r\n" + strSRecMsg);
//Thread.Sleep(3000);
//socketServer.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:"+strSRecMsg));
//發送客戶端數據
if (ClientConnectionItems.Count > 0)
{
foreach (var socketTemp in ClientConnectionItems)
{
socketTemp.Value.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:" + strSRecMsg));
}
}
}
catch (Exception)
{
ClientConnectionItems.Remove(socketServer.RemoteEndPoint.ToString());
//提示套接字監聽異常
Console.WriteLine("\r\n[客戶端\"" + socketServer.RemoteEndPoint + "\"已經中斷連接! 客戶端數量:" + ClientConnectionItems.Count+"]");
//關閉之前accept出來的和客戶端進行通信的套接字
socketServer.Close();
break;
}
}
}
}Client端代碼:
class Program
{
//創建1個客戶端套接字和1個負責監聽服務端請求的線程
static Thread ThreadClient = null;
static Socket SocketClient = null;
static void Main(string[] args)
{
try
{
int port = 6000;
string host = "127.0.0.1";//服務器端ip地址
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
//定義一個套接字監聽
SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
//客戶端套接字連接到網絡節點上,用的是Connect
SocketClient.Connect(ipe);
}
catch (Exception)
{
Console.WriteLine("連接失??!\r\n");
Console.ReadLine();
return;
}
ThreadClient = new Thread(Recv);
ThreadClient.IsBackground = true;
ThreadClient.Start();
Thread.Sleep(1000);
Console.WriteLine("請輸入內容<按Enter鍵發送>:\r\n");
while(true)
{
string sendStr = Console.ReadLine();
ClientSendMsg(sendStr);
}
//int i = 1;
//while (true)
//{
// Console.Write("請輸入內容:");
// string sendStr = Console.ReadLine();
// Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// clientSocket.Connect(ipe);
// //send message
// //byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr);
// byte[] sendBytes = Encoding.GetEncoding("utf-8").GetBytes(sendStr);
// //Thread.Sleep(4000);
// clientSocket.Send(sendBytes);
// //receive message
// string recStr = "";
// byte[] recBytes = new byte[4096];
// int bytes = clientSocket.Receive(recBytes, recBytes.Length, 0);
// //recStr += Encoding.ASCII.GetString(recBytes, 0, bytes);
// recStr += Encoding.GetEncoding("utf-8").GetString(recBytes, 0, bytes);
// Console.WriteLine(recStr);
// clientSocket.Close();
// if (i >= 100)
// {
// break;
// }
// i++;
//}
//Console.ReadLine();
//return;
//string result = String.Empty;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
//接收服務端發來信息的方法
public static void Recv()
{
int x = 0;
//持續監聽服務端發來的消息
while (true)
{
try
{
//定義一個1M的內存緩沖區,用于臨時性存儲接收到的消息
byte[] arrRecvmsg = new byte[1024 * 1024];
//將客戶端套接字接收到的數據存入內存緩沖區,并獲取長度
int length = SocketClient.Receive(arrRecvmsg);
//將套接字獲取到的字符數組轉換為人可以看懂的字符串
string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
if (x == 1)
{
Console.WriteLine("\r\n服務器:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "\r\n" + strRevMsg+"\r\n");
}
else
{
Console.WriteLine(strRevMsg + "\r\n");
x = 1;
}
}
catch (Exception ex)
{
Console.WriteLine("遠程服務器已經中斷連接!" + ex.Message + "\r\n");
break;
}
}
}
//發送字符信息到服務端的方法
public static void ClientSendMsg(string sendMsg)
{
//將輸入的內容字符串轉換為機器可以識別的字節數組
byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
//調用客戶端套接字發送字節數組
SocketClient.Send(arrClientSendMsg);
}
}測試結果:
server端:

client端:



關于“C#使用Socket實現服務器與多個客戶端通信的方法”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。