多线程Socket 编程实现局域网通信
利用多线程 Socket 编程实现 TCP 协议。 在局域网内实现多个 IP 的信息通信。
服务器:
接收所有局域网内客户端发来的信息, 并将此信息转发给其他所以的客户端。 采用多线程实现局域网内每个在线客户端的信息监听。
客户端:
接受服务器发来的信息,或发送信息给服务器, 再有服务器转发给其他在线客户端。
服务器代码:
 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;//在线客户数量 private int socketNum;//连接服务段的数量 private Socket[] socketUser = new Socket[40];//存储在线的客户端
// 将客服端 nowClient 发来的信息 data,发送给其他在线的每个客户端,不包括 nowClient客服端。 private void SendAllUser(byte[] data, Socket nowClient) { if (userNum > 0) { for (int i = 0; i < socketNum; i++) { if (socketUser[i].Equals(nowClient)) continue;
// 在发送过程中可能有些客户已经离线,会发生异常 try { socketUser[i].Send(data); } catch { // 当一个发现异常后,说明 socket[i] 已经离线,需要从socketUser[] 数组中将其删除 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]; // 不段的接受客户端发来的信息, 当客户端离线后,退出。 try { res = nowClient.Receive(bytes); } catch { // client 离线,更新userNum 值 userNum--; Console.WriteLine("现在有:{0} 个客户在连接中。", userNum); return; } string str = Encoding.UTF8.GetString(bytes, 0, res); byte[] data = Encoding.UTF8.GetBytes(str); //将该信息发送给其他客户端 SendAllUser(data, nowClient); } }
// 侦听上线的客户端 private void AccpetUser() { while (true) { // 当侦听到一个客户端上线后,更新socketUser[],并给此客户端开一个接受信息的线程 Socket nowClient = server.Accept(); socketUser[socketNum++] = nowClient; userNum++; Console.WriteLine("现在有:{0} 个客户在连接中。", userNum);
// 开一个线程, 接受 nowClient 发来的信息。 // 这里调用的方法为有参数的方法, 需要使用委托。 Thread nowThread = new Thread(new ParameterizedThreadStart(ReceiveData)); //nowThread.IsBackground = true; nowThread.Start(nowClient); } }
// 构造函数 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);
// 将套接字与本地终结点绑定 server.Bind(iep);
//在本地 3000 端口行上进行监听 server.Listen(20);
Console.WriteLine("等待客户级进行连接..."); 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("与服务器断开连接!"); 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");// 服务器的 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("无法连接到服务器"); 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("断开与服务器的连接..."); ads.client.Close(); Console.ReadLine(); } } }

|