C#- Socket实现服务器与多个客户端通信
因为工作需要,做一个C#的小DEMO来调试程序,好久没有写过SOCKET在网上找到一篇,代码看起来比较清晰明了。于是转载记录在这里,原文网址是:https://blog.csdn.net/luming666/article/details/79125453
Server端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | 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端:
代码下载地址:http://download.csdn.net/download/luming666/10217302
分类:
.NET/C#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2014-09-03 ASP.NET- 查找Repeater控件中嵌套的控件
2012-09-03 设计模式- 观察者模式