3.服务端广播,简易的多人聊天
703 字约 2 分钟
2024-12-11
一、UdpServer
在UdpServer.cs中添加一个集合用来存放发送过消息的客户端。创建一个用来处理接收消息的方法,并广播给其它所有添加进集合的客户端,在收到消息之后调用HandleBroadcastMessage()方法,完整的代码如下:
private static int port = 5000;
private static UdpClient udpServer = new UdpClient(port);
// 用来存放客户端的连接
private static List<IPEndPoint> clients = new List<IPEndPoint>();
public static void Start()
{
Console.WriteLine("UDP 聊天服务器已启动,等待消息...");
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, port);
ReceiveMessages();
}
/// <summary>
/// 循环接收信息
/// </summary>
private static void ReceiveMessages()
{
// 接收所有ip发送过来的UDP消息
IPEndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
// 一直接收消息
while (true)
{
try
{
byte[] receivedData = udpServer.Receive(ref clientEndPoint);
Console.WriteLine(Encoding.UTF8.GetString(receivedData));
// 处理接收到的消息
HandleBroadcastMessage(receivedData, clientEndPoint);
}
catch (SocketException ex)
{
Console.WriteLine($"SocketException: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
}
}
/// <summary>
/// 处理接收到的消息
/// </summary>
/// <param name="msg">消息</param>
/// <param name="client">发送这个消息的客户端</param>
private static void HandleBroadcastMessage(byte[] msg, IPEndPoint client)
{
// 如果这个客户端没有被添加进来,那么就添加到这个集合中
if (!clients.Contains(client))
{
clients.Add(client);
}
// 把这个消息广播给所有的客户端(除去发送者)
foreach (IPEndPoint endpoint in clients)
{
if (!endpoint.Equals(client))
{
udpServer.Send(msg, msg.Length, endpoint);
}
}
}
二、UdpClient
在Program.cs中添加一个ReceiveMessages()方法用来处理接收到的消息,在main()方法中开启接收消息的线程,完整代码如下:
private const string ip = "127.0.0.1";
private static UdpClient udpClient = new UdpClient();
// 请替换为实际的服务器 IP
private static IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ip), port);
static void Main()
{
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, 0)); // 0:自己分配端口号 也可以指定具体的端口
// 发送消息的线程
Thread sendThread = new Thread(SendMessage);
sendThread.Start();
// 接收消息的线程
Thread receiveThread = new Thread(ReceiveMessages);
receiveThread.Start();
Console.WriteLine("UDP 聊天客户端已启动,输入消息发送(输入 'exit' 退出):");
}
private static void SendMessage()
{
// 循环发送消息
while (true)
{
string str = Console.ReadLine();
if (str.ToLower() == "exit") break;
byte[] msg = Encoding.UTF8.GetBytes(str);
udpClient.Send(msg, msg.Length, serverEndPoint);
}
//清理资源
udpClient.Close();
}
private static void ReceiveMessages()
{
IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Any, port);
while (true)
{
try
{
byte[] receivedData = udpClient.Receive(ref listenEndPoint); // 收到消息
Console.WriteLine("收到一则消息:" + Encoding.UTF8.GetString(receivedData));
}
catch (ObjectDisposedException)
{
Console.WriteLine("UdpClient已关闭。");
break; // 可以选择停止接收
}
catch (Exception ex)
{
Console.WriteLine($"异常: {ex.Message}");
}
}
}