|
多線程Socket 編程實(shí)現(xiàn)局域網(wǎng)通信
利用多線程 Socket 編程實(shí)現(xiàn) TCP 協(xié)議。 在局域網(wǎng)內(nèi)實(shí)現(xiàn)多個 IP 的信息通信。
服務(wù)器:
接收所有局域網(wǎng)內(nèi)客戶端發(fā)來的信息, 并將此信息轉(zhuǎn)發(fā)給其他所以的客戶端。 采用多線程實(shí)現(xiàn)局域網(wǎng)內(nèi)每個在線客戶端的信息監(jiān)聽。
客戶端:
接受服務(wù)器發(fā)來的信息,或發(fā)送信息給服務(wù)器, 再有服務(wù)器轉(zhuǎn)發(fā)給其他在線客戶端。
服務(wù)器代碼:
 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading;
namespace multithreadserv { class Threadtcpserver { private Socket server; private int userNum;//在線客戶數(shù)量 private int socketNum;//連接服務(wù)段的數(shù)量 private Socket[] socketUser = new Socket[40];//存儲在線的客戶端
// 將客服端 nowClient 發(fā)來的信息 data,發(fā)送給其他在線的每個客戶端,不包括 nowClient客服端。 private void SendAllUser(byte[] data, Socket nowClient) { if (userNum > 0) { for (int i = 0; i < socketNum; i++) { if (socketUser[i].Equals(nowClient)) continue;
// 在發(fā)送過程中可能有些客戶已經(jīng)離線,會發(fā)生異常 try { socketUser[i].Send(data); } catch { // 當(dāng)一個發(fā)現(xiàn)異常后,說明 socket[i] 已經(jīng)離線,需要從socketUser[] 數(shù)組中將其刪除 Socket temp = socketUser[i]; socketUser[i] = socketUser[socketNum - 1]; i--; socketNum--; } } } }
// 客戶端 client 的接受信息的方法 private void ReceiveData(object client) { Socket nowClient = (Socket)client; while (true) { int res = 0; byte[] bytes = new byte[1024]; // 不段的接受客戶端發(fā)來的信息, 當(dāng)客戶端離線后,退出。 try { res = nowClient.Receive(bytes); } catch { // client 離線,更新userNum 值 userNum--; Console.WriteLine("現(xiàn)在有:{0} 個客戶在連接中。", userNum); return; } string str = Encoding.UTF8.GetString(bytes, 0, res); byte[] data = Encoding.UTF8.GetBytes(str); //將該信息發(fā)送給其他客戶端 SendAllUser(data, nowClient); } }
// 偵聽上線的客戶端 private void AccpetUser() { while (true) { // 當(dāng)偵聽到一個客戶端上線后,更新socketUser[],并給此客戶端開一個接受信息的線程 Socket nowClient = server.Accept(); socketUser[socketNum++] = nowClient; userNum++; Console.WriteLine("現(xiàn)在有:{0} 個客戶在連接中。", userNum);
// 開一個線程, 接受 nowClient 發(fā)來的信息。 // 這里調(diào)用的方法為有參數(shù)的方法, 需要使用委托。 Thread nowThread = new Thread(new ParameterizedThreadStart(ReceiveData)); //nowThread.IsBackground = true; nowThread.Start(nowClient); } }
// 構(gòu)造函數(shù) public Threadtcpserver() { userNum = 0; socketNum = 0;
//初始化 IP 地址 IPAddress local = IPAddress.Parse("192.168.1.101");//客戶端的 IPAddress 地址 IPEndPoint iep = new IPEndPoint(local, 3000);// 端口為3000
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 將套接字與本地終結(jié)點(diǎn)綁定 server.Bind(iep);
//在本地 3000 端口行上進(jìn)行監(jiān)聽 server.Listen(20);
Console.WriteLine("等待客戶級進(jìn)行連接..."); AccpetUser(); } static void Main(string[] args) { Threadtcpserver instance = new Threadtcpserver(); } }
}

客服端代碼:
 using System; using System.Collections.Generic; using System.Text; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading;
namespace multithreadclient { class ClientSocket { // public string names; public Socket client; public ClientSocket() { client = null; } public void ReceiveData() { byte[] data = new byte[1024]; while (true) { int res = 0; try { res = client.Receive(data); } catch { Console.WriteLine("與服務(wù)器斷開連接!"); return; }
Console.WriteLine(Encoding.UTF8.GetString(data, 0, res)); Console.WriteLine(); } } static void Main(string[] args) { //byte[] buf = new byte[1024]; ClientSocket ads = new ClientSocket();
IPAddress local = IPAddress.Parse("192.168.1.101");// 服務(wù)器的 IPAddres 地址 IPEndPoint iep = new IPEndPoint(local, 3000); try { ads.client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ads.client.Connect(iep); } catch (SocketException) { Console.WriteLine("無法連接到服務(wù)器"); Console.ReadLine(); return; } finally { }
Console.Write("連接成功, 請輸入昵稱:"); string names = Console.ReadLine();
Thread newThread = new Thread(new ThreadStart(ads.ReceiveData)); newThread.Start(); names += " 說:"; while (true) { // 在控制臺上輸入一條消息 //Console.WriteLine("我想說:"); Console.WriteLine(); string input = Console.ReadLine(); input = names + input; ads.client.Send(Encoding.UTF8.GetBytes(input)); } Console.WriteLine("斷開與服務(wù)器的連接..."); ads.client.Close(); Console.ReadLine(); } } }

|