本文实例为大家分享了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();
?? ??? ?}
?? ?}
}
客户端运行效果:
①客户端先于服务端运行
②客户端迟于服务端运行
暂时总效果:
功能完善:
①客户端连上服务端后若服务端断开再打开,客户端无法重连
②心跳包重连
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持www.admin99.cn。