C#使用Socket實現(xiàn)本地多人聊天室
本文實例為大家分享了C#使用Socket實現(xiàn)本地多人聊天室的具體代碼,供大家參考,具體內(nèi)容如下
【腳本一:Server端】
使用本機地址:127.0.0.1
完整代碼
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; ?? ??? ??? ?//創(chuàng)建IP終結(jié)點,把IP地址與端口綁定到網(wǎng)絡(luò)終結(jié)點上 ?? ??? ??? ?IPEndPoint endPoint = new IPEndPoint(address, port); ?? ??? ??? ?//創(chuàng)建客戶端套接字 ?? ??? ??? ?mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ?? ??? ??? ?///監(jiān)聽套接字終結(jié)點 ?? ??? ??? ?mySocket.Bind(endPoint); ?? ??? ??? ?//服務(wù)端可接收客戶端連接數(shù)量為無限個 ?? ??? ??? ?mySocket.Listen(0); ?? ??? ??? ?//開啟線程監(jiān)聽客戶端 ?? ??? ??? ?Thread myThread = new Thread(Listen_Con); ?? ??? ??? ?myThread.Start(); ?? ??? ??? ?Console.WriteLine("開始監(jiān)聽..."); ?? ??? ?} ? ?? ??? ?/// <summary> ?? ??? ?/// 接收連接的客戶端并存儲客戶端的信息 ?? ??? ?/// </summary> ?? ??? ?/// <param name="obj"></param> ?? ??? ?public void Listen_Con(Object obj) ?? ??? ?{ ?? ??? ??? ?Socket cliSocket = null; ?? ??? ??? ?//持續(xù)監(jiān)聽客戶端的請求 ?? ??? ??? ?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 = "[客戶端結(jié)點:" + 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> ?? ??? ?/// 接收已連接的客戶端發(fā)送的消息 ?? ??? ?/// </summary> ?? ??? ?/// <param name="socket"></param> ?? ??? ?public void Receive_Con(Object socket) ?? ??? ?{ ?? ??? ??? ?Socket client = socket as Socket; ?? ??? ??? ?while (true) ?? ??? ??? ?{ ?? ??? ??? ??? ?//創(chuàng)建大小為1024*1024的內(nèi)存緩沖區(qū)(1M) ?? ??? ??? ??? ?byte[] recBytes = new byte[1024 * 1024]; ?? ??? ??? ??? ?//嘗試把接收的字節(jié)存儲到緩沖區(qū) ?? ??? ??? ??? ?try ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?int length = client.Receive(recBytes); ?? ??? ??? ??? ??? ?//把機器接收的字節(jié)數(shù)組轉(zhuǎn)換為string ?? ??? ??? ??? ??? ?string recMsg = Encoding.UTF8.GetString(recBytes, 0, length); ?? ??? ??? ??? ??? ?//將服務(wù)器接收到的信息轉(zhuǎn)發(fā)到所有已連接的客戶端 ?? ??? ??? ??? ??? ?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("[客戶端終結(jié)點:" + 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("[服務(wù)端]:"+MsgToAll); ?? ??? ??? ??? ??? ?curCliSoc.Send(ByteToAll); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?catch(Exception) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?Console.WriteLine("ERROR:" + curCliSoc.RemoteEndPoint + "已與服務(wù)端斷開!"); ?? ??? ??? ??? ??? ?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端運行結(jié)果:
【腳本二: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("無法連接到服務(wù)端,請重試..."); ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?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("已與服務(wù)端斷開連接..."); ?? ??? ??? ??? ??? ?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(); ?? ??? ?} ?? ?} }
客戶端運行效果:
①客戶端先于服務(wù)端運行
②客戶端遲于服務(wù)端運行
暫時總效果:
功能完善:
①客戶端連上服務(wù)端后若服務(wù)端斷開再打開,客戶端無法重連
②心跳包重連
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C# 動態(tài)調(diào)用WebService的示例
這篇文章主要介紹了C# 動態(tài)調(diào)用WebService的示例,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下2020-11-11c# 重載WndProc,實現(xiàn)重寫“最小化”的實現(xiàn)方法
在做“亦歌桌面版”的時候,發(fā)現(xiàn)當(dāng)打開歌詞狀態(tài)下,用最小化隱藏窗體到托盤的話(如下code #1),在調(diào)出發(fā)現(xiàn)歌詞縮小了(雖然顯現(xiàn)的窗體大小跟剛才一樣),從這點看調(diào)用該方法其實窗體大小是改變了的(這個過程只是不可視而已)。2009-02-02Unity游戲開發(fā)實現(xiàn)背包系統(tǒng)的示例詳解
這篇文章主要為大家介紹了Unity游戲開發(fā)實現(xiàn)背包系統(tǒng)的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08