C#使用Socket實(shí)現(xiàn)本地多人聊天室
本文實(shí)例為大家分享了C#使用Socket實(shí)現(xiàn)本地多人聊天室的具體代碼,供大家參考,具體內(nèi)容如下
【腳本一:Server端】
使用本機(jī)地址: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é)點(diǎn),把IP地址與端口綁定到網(wǎng)絡(luò)終結(jié)點(diǎn)上
?? ??? ??? ?IPEndPoint endPoint = new IPEndPoint(address, port);
?? ??? ??? ?//創(chuàng)建客戶端套接字
?? ??? ??? ?mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
?? ??? ??? ?///監(jiān)聽(tīng)套接字終結(jié)點(diǎn)
?? ??? ??? ?mySocket.Bind(endPoint);
?? ??? ??? ?//服務(wù)端可接收客戶端連接數(shù)量為無(wú)限個(gè)
?? ??? ??? ?mySocket.Listen(0);
?? ??? ??? ?//開(kāi)啟線程監(jiān)聽(tīng)客戶端
?? ??? ??? ?Thread myThread = new Thread(Listen_Con);
?? ??? ??? ?myThread.Start();
?? ??? ??? ?Console.WriteLine("開(kāi)始監(jiān)聽(tīng)...");
?? ??? ?}
?
?? ??? ?/// <summary>
?? ??? ?/// 接收連接的客戶端并存儲(chǔ)客戶端的信息
?? ??? ?/// </summary>
?? ??? ?/// <param name="obj"></param>
?? ??? ?public void Listen_Con(Object obj)
?? ??? ?{
?? ??? ??? ?Socket cliSocket = null;
?? ??? ??? ?//持續(xù)監(jiān)聽(tīng)客戶端的請(qǐng)求
?? ??? ??? ?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é)點(diǎn):" + 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é)存儲(chǔ)到緩沖區(qū)
?? ??? ??? ??? ?try
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?int length = client.Receive(recBytes);
?? ??? ??? ??? ??? ?//把機(jī)器接收的字節(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);
?? ??? ??? ??? ??? ?//客戶端斷開(kāi)的異常
?? ??? ??? ??? ??? ?Console.WriteLine("[客戶端" + (client.RemoteEndPoint as IPEndPoint).Address + "已斷開(kāi)]");
?? ??? ??? ??? ??? ?Console.WriteLine("[客戶端終結(jié)點(diǎn):" + client.RemoteEndPoint+"]");
?? ??? ??? ??? ??? ?//斷開(kāi)套接字
?? ??? ??? ??? ??? ?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ù)端斷開(kāi)!");
?? ??? ??? ??? ??? ?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端運(yùn)行結(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ú)法連接到服務(wù)端,請(qǐng)重試...");
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?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ù)端斷開(kāi)連接...");
?? ??? ??? ??? ??? ?break;
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?
?? ??? ?public void SendToSer()
?? ??? ?{
?? ??? ??? ?while (true)
?? ??? ??? ?{
?? ??? ??? ??? ?try
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?string SendMsg = Console.ReadLine();
?? ??? ??? ??? ??? ?myClient.Send(Encoding.UTF8.GetBytes(SendMsg));
?? ??? ??? ??? ?}
?? ??? ??? ??? ?catch (Exception)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?Console.WriteLine("[SendToSer]已斷開(kāi)連接");
?? ??? ??? ??? ??? ?break;
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}
?
?? ?public class ClienMain
?? ?{
?? ??? ?static void Main(string[] Args)
?? ??? ?{
?? ??? ??? ?Client c1 = new Client();
?? ??? ??? ?c1.Connect_To_Ser(8800);
?? ??? ??? ?c1.SendToSer();
?? ??? ?}
?? ?}
}客戶端運(yùn)行效果:
①客戶端先于服務(wù)端運(yùn)行

②客戶端遲于服務(wù)端運(yùn)行

暫時(shí)總效果:

功能完善:
①客戶端連上服務(wù)端后若服務(wù)端斷開(kāi)再打開(kāi),客戶端無(wú)法重連
②心跳包重連
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#正則表達(dá)式(Regex類)用法實(shí)例總結(jié)
正則表達(dá)式的主要作用是驗(yàn)證字符串的值是否滿足一定的規(guī)則,在頁(yè)面輸入數(shù)據(jù)驗(yàn)證方面的應(yīng)用比較多,下面這篇文章主要給大家介紹了關(guān)于C#正則表達(dá)式(Regex類)用法的相關(guān)資料,需要的朋友可以參考下2022-08-08
C#中使用DataContractSerializer類實(shí)現(xiàn)深拷貝操作示例
這篇文章主要介紹了C#中使用DataContractSerializer類實(shí)現(xiàn)深拷貝操作示例,本文給出了實(shí)現(xiàn)深拷貝方法、測(cè)試深拷貝方法例子、DataContractSerializer類實(shí)現(xiàn)深拷貝的原理等內(nèi)容,需要的朋友可以參考下2015-06-06
Unity實(shí)現(xiàn)角色受擊身體邊緣發(fā)光特效
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)角色受擊身體邊緣發(fā)光特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
unity實(shí)現(xiàn)簡(jiǎn)單的貪吃蛇游戲
這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)簡(jiǎn)單的貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
c# 判斷是否為空然后賦值的4種實(shí)現(xiàn)方法
下面小編就為大家分享一篇c# 判斷是否為空然后賦值的4種實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12

