本文实例为大家分享了C#使用Socket实现本地多人聊天室的具体代码,供大家参考,具体内容如下
【脚本一:Server端】完整代码
using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; ? namespace ConsoleApp1 { ?? ?public class Server ?? ?{ ?? ??? ?Socket mySocket = null; ?? ??? ?Dictionary<IPAddress, Socket> cliDic = new Dictionary<IPAddress, Socket>(); ? ?? ??? ?public void Connect(int port) ?? ??? ?{ ?? ??? ??? ?string IP = "127.0.0.1"; ?? ??? ??? ?//IPAddress IPAddress = IPAddress.Parse("127.0.0.1"); ?? ??? ??? ?IPAddress address = IPAddress.Any; ?? ??? ??? ?//创建IP终结点,把IP地址与端口绑定到网络终结点上 ?? ??? ??? ?IPEndPoint endPoint = new IPEndPoint(address, port); ?? ??? ??? ?//创建客户端套接字 ?? ??? ??? ?mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ?? ??? ??? ?///监听套接字终结点 ?? ??? ??? ?mySocket.Bind(endPoint); ?? ??? ??? ?//服务端可接收客户端连接数量为无限个 ?? ??? ??? ?mySocket.Listen(0); ?? ??? ??? ?//开启线程监听客户端 ?? ??? ??? ?Thread myThread = new Thread(Listen_Con); ?? ??? ??? ?myThread.Start(); ?? ??? ??? ?Console.WriteLine("开始监听..."); ?? ??? ?} ? ?? ??? ?/// <summary> ?? ??? ?/// 接收连接的客户端并存储客户端的信息 ?? ??? ?/// </summary> ?? ??? ?/// <param name="obj"></param> ?? ??? ?public void Listen_Con(Object obj) ?? ??? ?{ ?? ??? ??? ?Socket cliSocket = null; ?? ??? ??? ?//持续监听客户端的请求 ?? ??? ??? ?while (true) ?? ??? ??? ?{ ?? ??? ??? ??? ?try ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?cliSocket = mySocket.Accept(); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?catch (Exception e) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?Console.WriteLine(e.Message); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?string cliEndPoint = cliSocket.RemoteEndPoint.ToString(); ?? ??? ??? ??? ?IPAddress cliAddress = (cliSocket.RemoteEndPoint as IPEndPoint).Address; ?? ??? ??? ??? ?int cliPort = (cliSocket.RemoteEndPoint as IPEndPoint).Port; ?? ??? ??? ??? ?cliDic.Add(cliAddress, cliSocket); ?? ??? ??? ??? ?string MsgStr = "[客户端结点:" + cliEndPoint + "\n+客户端IP:" + cliAddress.ToString() + "\n客户端端口:" + ?? ??? ??? ??? ??? ?cliPort.ToString() + "\n已连接]"; ?? ??? ??? ??? ?byte[] MsgBytes = Encoding.UTF8.GetBytes(MsgStr); ?? ??? ??? ??? ?cliSocket.Send(MsgBytes); ? ?? ??? ??? ??? ?Thread rec_Cli = new Thread(Receive_Con); ?? ??? ??? ??? ?rec_Cli.Start(cliSocket); ?? ??? ??? ??? ?Thread sed_Cli = new Thread(SendToCli); ?? ??? ??? ??? ?sed_Cli.Start(cliSocket); ?? ??? ??? ?} ?? ??? ?} ? ?? ??? ?/// <summary> ?? ??? ?/// 接收已连接的客户端发送的消息 ?? ??? ?/// </summary> ?? ??? ?/// <param name="socket"></param> ?? ??? ?public void Receive_Con(Object socket) ?? ??? ?{ ?? ??? ??? ?Socket client = socket as Socket; ?? ??? ??? ?while (true) ?? ??? ??? ?{ ?? ??? ??? ??? ?//创建大小为1024*1024的内存缓冲区(1M) ?? ??? ??? ??? ?byte[] recBytes = new byte[1024 * 1024]; ?? ??? ??? ??? ?//尝试把接收的字节存储到缓冲区 ?? ??? ??? ??? ?try ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?int length = client.Receive(recBytes); ?? ??? ??? ??? ??? ?//把机器接收的字节数组转换为string ?? ??? ??? ??? ??? ?string recMsg = Encoding.UTF8.GetString(recBytes, 0, length); ?? ??? ??? ??? ??? ?//将服务器接收到的信息转发到所有已连接的客户端 ?? ??? ??? ??? ??? ?if (cliDic.Count > 0) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?foreach (var soc in cliDic) ?? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ?soc.Value.Send(Encoding.UTF8.GetBytes("[" + soc.Value.RemoteEndPoint + "]:" + recMsg)); ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?Console.WriteLine("[" + client.RemoteEndPoint + "]:" + recMsg); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?catch (Exception) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?cliDic.Remove((client.RemoteEndPoint as IPEndPoint).Address); ?? ??? ??? ??? ??? ?//客户端断开的异常 ?? ??? ??? ??? ??? ?Console.WriteLine("[客户端" + (client.RemoteEndPoint as IPEndPoint).Address + "已断开]"); ?? ??? ??? ??? ??? ?Console.WriteLine("[客户端终结点:" + client.RemoteEndPoint+"]"); ?? ??? ??? ??? ??? ?//断开套接字 ?? ??? ??? ??? ??? ?client.Close(); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ? ?? ??? ?public void SendToCli(object obj) ?? ??? ?{ ?? ??? ??? ?Socket curCliSoc = obj as Socket; ?? ??? ??? ?while (true) ?? ??? ??? ?{ ?? ??? ??? ??? ?byte[] ByteToAll = new byte[1024 * 1024]; ?? ??? ??? ??? ?try ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?string MsgToAll = Console.ReadLine(); ?? ??? ??? ??? ??? ?ByteToAll = Encoding.UTF8.GetBytes("[服务端]:"+MsgToAll); ?? ??? ??? ??? ??? ?curCliSoc.Send(ByteToAll); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?catch(Exception) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?Console.WriteLine("ERROR:" + curCliSoc.RemoteEndPoint + "已与服务端断开!"); ?? ??? ??? ??? ??? ?curCliSoc.Close(); ?? ??? ??? ??? ??? ?if(cliDic.ContainsKey((curCliSoc.RemoteEndPoint as IPEndPoint).Address)) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?cliDic.Remove((curCliSoc.RemoteEndPoint as IPEndPoint).Address); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ?? ?} ? ?? ?public class ServerMain ?? ?{ ?? ??? ?static void Main(string[] args) ?? ??? ?{ ?? ??? ??? ?Server s1 = new Server(); ?? ??? ??? ?s1.Connect(8800); ?? ??? ?} ?? ?} }
Server端运行结果:
【脚本二:Client端】
完整代码
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; ? namespace ConsoleApp1 { ?? ?public class Client ?? ?{ ?? ??? ?string SerIP = "127.0.0.1"; ?? ??? ?Socket myClient = null; ?? ??? ?Thread ConnectThread = null; ?? ??? ?IPAddress SerAdd; ?? ??? ?IPEndPoint SerEP; ?? ??? ?public void Connect_To_Ser(int port) ?? ??? ?{ ?? ??? ??? ?myClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ?? ??? ??? ?SerAdd = IPAddress.Parse(SerIP); ?? ??? ??? ?SerEP = new IPEndPoint(SerAdd, port); ?? ??? ??? ?while (true) ?? ??? ??? ?{ ?? ??? ??? ??? ?try ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?myClient.Connect(SerEP); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?catch ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?Console.WriteLine("无法连接到服务端,请重试..."); ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?ConnectThread = new Thread(Receive_Ser); ?? ??? ??? ?ConnectThread.Start(); ?? ??? ?} ? ?? ??? ?public void Receive_Ser() ?? ??? ?{ ?? ??? ??? ?while (true) ?? ??? ??? ?{ ?? ??? ??? ??? ?byte[] SerBytes = new byte[1024 * 1024]; ?? ??? ??? ??? ?try ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?int length = myClient.Receive(SerBytes); ?? ??? ??? ??? ??? ?string Msg = Encoding.UTF8.GetString(SerBytes, 0, length); ?? ??? ??? ??? ??? ?Console.WriteLine(Msg); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?catch (Exception) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?Console.WriteLine("已与服务端断开连接..."); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ? ?? ??? ?public void SendToSer() ?? ??? ?{ ?? ??? ??? ?while (true) ?? ??? ??? ?{ ?? ??? ??? ??? ?try ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?string SendMsg = Console.ReadLine(); ?? ??? ??? ??? ??? ?myClient.Send(Encoding.UTF8.GetBytes(SendMsg)); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?catch (Exception) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?Console.WriteLine("[SendToSer]已断开连接"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ?? ?} ? ?? ?public class ClienMain ?? ?{ ?? ??? ?static void Main(string[] Args) ?? ??? ?{ ?? ??? ??? ?Client c1 = new Client(); ?? ??? ??? ?c1.Connect_To_Ser(8800); ?? ??? ??? ?c1.SendToSer(); ?? ??? ?} ?? ?} }
客户端运行效果:
①客户端先于服务端运行
②客户端迟于服务端运行
暂时总效果:
功能完善:
①客户端连上服务端后若服务端断开再打开,客户端无法重连
②心跳包重连
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
查看更多关于C#使用Socket实现本地多人聊天室的详细内容...