服务功能实现
技术点
- 传输方式:TCP 协议保证数据有序、无丢失传输,通过字节流拆包 / 封包机制解决粘包 / 半包问题。
- 协议格式:采用 “4 字节长度头 + JSON 消息体” 的二进制协议,解决 TCP 粘包 / 半包问题。
- 消息格式:
MessageStyle消息格式,所有的消息都使用MessageStyle,包裹将消息放到Message中,然后设置不同的public MessageTypeEnum Type { get; set; }
项目执行流程
- 程序入口执行:调用Main方法,依次执行
RegisterApplicationEvents和InitializeSocket,进行事件注册和socket初始化 - 启动
AcceptClientConnections线程:循环调用_serverSocket.Accept()阻塞监听客户端连接请求,该线程为后台线程,不阻塞主线程 - 链接完成后使用
HandleConsoleInput启动控制台命令
客户端连接
-
接收客户端连接
AcceptClientConnections
调用GenerateUniqueClientId生成CLIENT_+GUID格式的唯一客户端 ID。
创建ClientInfo对象,存储客户端 Socket、ID、最后活跃时间、连接状态等信息。
加锁将ClientInfo添加到_clients字典,线程安全。
控制台输出客户端连接信息(ID、IP、端口)。 -
发送欢迎消息
调用SendWelcomeMessageToClient,发送欢迎消息,通过SendMessageToClient按 “4 字节长度头 + JSON 消息体” 协议发送给客户端,完成客户端身份初始化。
启动客户端消息处理线程
// 启动处理客户端消息的线程
Thread clientThread = new Thread(() => HandleClient(clientId));
clientThread.IsBackground = true;
clientThread.Start();
为当前客户端分配独立的 private static void HandleClient(string clientId) 线程。
3. 然后接收和处理客户端发来的消息 ProcessClientMessage(clientId, message);
4. 解析数据,先读取四字节长度的消息,然后一直接收并解析数据
// 读取4字节的消息长度
int lengthBytesRead = 0;
while (lengthBytesRead < 4)
{
int read = clientInfo.Socket.Receive(
lengthBuffer,
lengthBytesRead,
4 - lengthBytesRead,
SocketFlags.None);
if (read == 0)
{
// 客户端断开连接
throw new SocketException((int) SocketError.ConnectionReset);
}
lengthBytesRead += read;
}
// 将4字节转换为消息长度(网络字节序转主机字节序)
int messageLength = BitConverter.ToInt32(lengthBuffer, 0);
messageLength = IPAddress.NetworkToHostOrder(messageLength);
// 根据长度读取完整消息
messageBuffer.SetLength(0);
- 处理各种消息
private static void HandleTextMessage(string clientId, MessageStyle message)
private static void HandleBroadcastMessage(string clientId, MessageStyle message)
private static void HandlePrivateMessage(string clientId, MessageStyle message)
private static void HandleSetUserName(string clientId, MessageStyle message)
等等-----
- 使用控制台发送命令
/// <summary>
/// 处理控制台输入
/// </summary>
private static void HandleConsoleInput()
{
Console.WriteLine("\n服务器命令:");
DeaultConsoleLine();
while (true)
{
try
{
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
continue;
var parts = input.Trim().Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 0) continue;
string command = parts[0].ToUpper();
string[] args = parts.Length > 1 ? parts.Skip(1).ToArray() : new string[0];
switch (command)
{
case "/EXIT":
break;
default:
Console.WriteLine("未知命令,输入 /help 查看可用命令");
break;
}
}
catch (Exception ex)
{
Console.WriteLine($"处理命令时出错: {ex.Message}");
}
}
}
项目引用


基础工具代码
仅需要生成客户端id这一个工具代码,只有一个地方使用到了,所以也可以删掉直接写到用地方。
/// <summary>
/// 生成客户端ID
/// </summary>
private static string GenerateClientId()
{
lock (_lock)
{
return $"CLIENT_{Guid.NewGuid():N}";
}
}
变量创建
/// <summary>
/// socket
/// </summary>
private static Socket _serverSocket;
/// <summary>
/// 客户端列表
/// </summary>
private static Dictionary<string, ClientInfo> _clients = new Dictionary<string, ClientInfo>();
/// <summary>
/// 线程锁
/// </summary>
private static object _lock = new object();
/// <summary>
/// 端口
/// </summary>
private static int Port = 23841;
socket链接
/// <summary>
/// 初始化socket
/// </summary>
private static void InitSocket()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipNode = new IPEndPoint(IPAddress.Any, Port);
try
{
_serverSocket.Bind(ipNode);
_serverSocket.Listen(10);
Console.WriteLine($"服务器已启动,监听端口: {Port}");
Console.WriteLine("等待客户端连接...");
// 启动接受连接的线程
Thread acceptThread = new Thread(AcceptClients);
acceptThread.IsBackground = true;
acceptThread.Start();
// 处理控制台输入
HandleConsoleInput();
}
catch (Exception ex)
{
Console.WriteLine($"服务器启动失败: {ex.Message}");
}
}
/// <summary>
/// 接受客户端连接的线程
/// </summary>
private static void AcceptClients()
{
while (true)
{
try
{
Socket clientSocket = _serverSocket.Accept();
// 生成客户端ID
string clientId = GenerateClientId();
// 创建客户端信息
ClientInfo clientInfo = new ClientInfo
{
ClientId = clientId,
Socket = clientSocket,
LastActiveTime = DateTime.Now,
IsConnected = true
};
// 添加到客户端字典
lock (_lock)
{
_clients[clientId] = clientInfo;
}
IPEndPoint clientEndPoint = (IPEndPoint)clientSocket.RemoteEndPoint;
Console.WriteLine($"客户端 {clientId} 已连接,IP: {clientEndPoint.Address}:{clientEndPoint.Port}");
// 发送欢迎消息和客户端ID
SendWelcomeMessage(clientId);
// 启动处理客户端消息的线程
Thread clientThread = new Thread(() => HandleClient(clientId));
clientThread.IsBackground = true;
clientThread.Start();
}
catch (Exception ex)
{
Console.WriteLine($"接受客户端连接时出错: {ex.Message}");
}
}
}
/// <summary>
/// 事件注册
/// </summary>
private static void EventRegistration()
{
AppDomain.CurrentDomain.ProcessExit += (s, e) =>
{
try
{
if (_serverSocket != null && _serverSocket.Connected)
{
_serverSocket.Shutdown(SocketShutdown.Both);
}
_serverSocket?.Close();
Console.WriteLine("服务器Socket已释放");
}
catch (Exception ex)
{
Console.WriteLine($"释放服务器Socket失败: {ex.Message}");
}
};
}
并且在Main中调用
static void Main(string[] args)
{
EventRegistration();
InitSocket();
}
事件处理
用户管理
发送欢迎消息,在用户连接之后
/// <summary>
/// 发送欢迎消息
/// </summary>
private static void SendWelcomeMessage(string clientId)
{
try
{
ClientInfo clientInfo;
lock (_lock)
{
if (!_clients.TryGetValue(clientId, out clientInfo))
{
return;
}
}
WelComMessageModel welComMessage = new WelComMessageModel("欢迎连接到Socket服务器!");
MessageStyle messageStyle = new MessageStyle
(
MessageTypeEnum.Welcome,
clientInfo.ClientId,
JsonConvert.SerializeObject(welComMessage)
);
SendMessage(clientInfo.ClientId, JsonConvert.SerializeObject(messageStyle));
}
catch (Exception ex)
{
Console.WriteLine($"发送欢迎消息失败: {ex.Message}");
}
}
/// <summary>
/// 移除客户端
/// </summary>
private static void RemoveClient(string clientId)
{
lock (_lock)
{
if (_clients.ContainsKey(clientId))
{
try
{
_clients[clientId].Socket.Shutdown(SocketShutdown.Both);
_clients[clientId].Socket.Close();
}
catch { }
_clients.Remove(clientId);
Console.WriteLine($"客户端 {clientId} 已从列表中移除");
}
}
}
消息事件
消息接收与消息预处理
/// <summary>
/// 处理客户端消息
/// </summary>
private static void HandleClient(string clientId)
{
ClientInfo clientInfo;
lock (_lock)
{
if (!_clients.TryGetValue(clientId, out clientInfo))
{ return; }
}
byte[] tempBuffer = new byte[1024];
try
{
byte[] lengthBuffer = new byte[4];
using (MemoryStream messageBuffer = new MemoryStream())
{
while (true)
{
// 读取4字节的消息长度
int lengthBytesRead = 0;
while (lengthBytesRead < 4)
{
int read = clientInfo.Socket.Receive(
lengthBuffer,
lengthBytesRead,
4 - lengthBytesRead,
SocketFlags.None);
if (read == 0)
{
// 客户端断开连接
throw new SocketException((int)SocketError.ConnectionReset);
}
lengthBytesRead += read;
}
// 将4字节转换为消息长度(网络字节序转主机字节序)
int messageLength = BitConverter.ToInt32(lengthBuffer, 0);
messageLength = IPAddress.NetworkToHostOrder(messageLength);
// 根据长度读取完整消息
messageBuffer.SetLength(0);
int totalBytesRead = 0;
while (totalBytesRead < messageLength)
{
int bytesToRead = Math.Min(tempBuffer.Length, messageLength - totalBytesRead);
int read = clientInfo.Socket.Receive(tempBuffer, 0, bytesToRead, SocketFlags.None);
if (read == 0)
{
// 客户端断开连接
throw new SocketException((int)SocketError.ConnectionReset);
}
messageBuffer.Write(tempBuffer, 0, read);
totalBytesRead += read;
}
// 处理消息
string message = Encoding.UTF8.GetString(messageBuffer.ToArray());
clientInfo.LastActiveTime = DateTime.Now;
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 客户端 {clientId} 发送: {message}");
// 解析客户端消息并处理
ProcessClientMessage(clientId, message);
}
}
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.ConnectionReset ||
ex.SocketErrorCode == SocketError.ConnectionAborted)
{
Console.WriteLine($"客户端 {clientId} 主动断开连接");
}
else if (ex.SocketErrorCode == SocketError.TimedOut)
{
Console.WriteLine($"客户端 {clientId} 连接超时");
}
else
{
Console.WriteLine($"客户端 {clientId} 网络异常: {ex.Message} (错误码: {ex.SocketErrorCode})");
}
}
catch (IOException ex)
{
Console.WriteLine($"客户端 {clientId} IO异常: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"客户端 {clientId} 未知异常: {ex.Message}");
}
finally
{
// 移除客户端
RemoveClient(clientId);
}
}
/// <summary>
/// 处理客户端发送的消息
/// </summary>
/// <param name="clientId">发送消息的客户端ID</param>
/// <param name="message">JSON格式的消息字符串</param>
private static void ProcessClientMessage(string clientId, string message)
{
try
{
// 反序列化基础消息结构
MessageStyle clientMessage = JsonConvert.DeserializeObject<MessageStyle>(message);
if (clientMessage == null)
{
Console.WriteLine($"客户端 {clientId} 发送无效消息格式: {message}");
return;
}
// 根据消息类型处理
switch (clientMessage.Type)
{
case MessageTypeEnum.Text:
HandleTextMessage(clientId, clientMessage);
break;
case MessageTypeEnum.Broadcast:
HandleBroadcastMessage(clientId, clientMessage);
break;
case MessageTypeEnum.PrivateMsg:
HandlePrivateMessage(clientId, clientMessage);
break;
case MessageTypeEnum.SetUserName:
HandleSetUserName(clientId, clientMessage);
break;
case MessageTypeEnum.Heartbeat:
HandleHeartbeatMessage(clientId, clientMessage);
break;
case MessageTypeEnum.Unknown:
HandleUnknownMessage(clientId, clientMessage);
break;
case MessageTypeEnum.ListRequest:
HandleListRequest(clientId);
break;
default:
Console.WriteLine($"客户端 {clientId} 发送未知消息类型: {clientMessage.Type}");
break;
}
}
catch (JsonSerializationException jsonEx)
{
Console.WriteLine($"客户端 {clientId} 消息反序列化失败: {jsonEx.Message},原始消息: {message}");
}
catch (Exception ex)
{
Console.WriteLine($"处理客户端 {clientId} 消息时出错: {ex.Message}");
}
}
处理文本消息
/// <summary>
/// 处理文本消息
/// </summary>
private static void HandleTextMessage(string clientId, MessageStyle message)
{
try
{
StandMessageModel textModel = JsonConvert.DeserializeObject<StandMessageModel>(message.Message);
string responseMsg = $"收到你的文本消息: {textModel.Message}";
// 回复发送者
MessageStyle response = new MessageStyle(MessageTypeEnum.Text, clientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", clientId, responseMsg)));
SendMessage(clientId, JsonConvert.SerializeObject(response));
}
catch (Exception ex)
{
Console.WriteLine($"处理文本消息失败: {ex.Message}");
}
}
处理广播消息
/// <summary>
/// 处理广播消息
/// </summary>
private static void HandleBroadcastMessage(string clientId, MessageStyle message)
{
try
{
StandMessageModel broadcastModel = JsonConvert.DeserializeObject<StandMessageModel>(message.Message);
string broadcastContent = $"[{GetClientName(clientId)}({clientId})] 广播: {broadcastModel.Message}";
// 构建广播消息
MessageStyle broadcastMsg = new MessageStyle(MessageTypeEnum.Broadcast, clientId,
JsonConvert.SerializeObject(new StandMessageModel(clientId, "ALL", broadcastContent)));
string broadcastJson = JsonConvert.SerializeObject(broadcastMsg);
// 发送给所有在线客户端,包括发送者自己
lock (_lock)
{
foreach (var client in _clients)
{
SendMessage(client.Key, broadcastJson);
}
}
Console.WriteLine($"客户端 {clientId} 发送广播: {broadcastModel.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"处理广播消息失败: {ex.Message}");
}
}
处理私聊消息
/// <summary>
/// 处理私聊消息
/// </summary>
private static void HandlePrivateMessage(string clientId, MessageStyle message)
{
try
{
StandMessageModel privateModel = JsonConvert.DeserializeObject<StandMessageModel>(message.Message);
string targetClientId = privateModel.TargetClientID;
string privateContent = privateModel.Message;
// 验证目标客户端是否存在
if (!_clients.ContainsKey(targetClientId))
{
// 回复发送者:目标不存在
string errorMsg = $"目标客户端 {targetClientId} 不存在或已离线";
MessageStyle errorResponse = new MessageStyle(MessageTypeEnum.Text, clientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", clientId, errorMsg)));
SendMessage(clientId, JsonConvert.SerializeObject(errorResponse));
return;
}
// 构建私聊消息
string senderName = GetClientName(clientId);
string privateMsgContent = $"[{senderName}({clientId})] 私聊: {privateContent}";
MessageStyle privateMsg = new MessageStyle(MessageTypeEnum.PrivateMsg, clientId,
JsonConvert.SerializeObject(new StandMessageModel(clientId, targetClientId, privateMsgContent)));
// 发送给目标客户端
SendMessage(targetClientId, JsonConvert.SerializeObject(privateMsg));
// 回复发送者:发送成功
string successMsg = $"已向 {targetClientId} 发送私聊消息: {privateContent}";
MessageStyle successResponse = new MessageStyle(MessageTypeEnum.Text, clientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", clientId, successMsg)));
SendMessage(clientId, JsonConvert.SerializeObject(successResponse));
Console.WriteLine($"客户端 {clientId} 向 {targetClientId} 发送私聊: {privateContent}");
}
catch (Exception ex)
{
Console.WriteLine($"处理私聊消息失败: {ex.Message}");
}
}
处理设置用户名
/// <summary>
/// 处理设置用户名
/// </summary>
private static void HandleSetUserName(string clientId, MessageStyle message)
{
try
{
StandMessageModel userNameModel = JsonConvert.DeserializeObject<StandMessageModel>(message.Message);
string newUserName = userNameModel.Message.Trim();
if (string.IsNullOrEmpty(newUserName))
{
// 回复错误
string errorMsg = "用户名不能为空";
MessageStyle errorResponse = new MessageStyle(MessageTypeEnum.Text, clientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", clientId, errorMsg)));
SendMessage(clientId, JsonConvert.SerializeObject(errorResponse));
return;
}
// 更新客户端用户名
lock (_lock)
{
if (_clients.ContainsKey(clientId))
{
_clients[clientId].ClientName = newUserName;
}
}
// 回复成功
string successMsg = newUserName;
MessageStyle successResponse = new MessageStyle(MessageTypeEnum.SetUserName, clientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", clientId, successMsg)));
SendMessage(clientId, JsonConvert.SerializeObject(successResponse));
Console.WriteLine($"客户端 {clientId} 设置用户名为: {newUserName}");
}
catch (Exception ex)
{
Console.WriteLine($"处理设置用户名失败: {ex.Message}");
}
}
处理心跳消息
/// <summary>
/// 处理心跳消息
/// </summary>
private static void HandleHeartbeatMessage(string clientId, MessageStyle message)
{
try
{
StandMessageModel heartbeatModel = JsonConvert.DeserializeObject<StandMessageModel>(message.Message);
// 回复心跳确认
string heartbeatMsg = "心跳确认 - 服务器已收到";
MessageStyle heartbeatResponse = new MessageStyle(MessageTypeEnum.Heartbeat, clientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", clientId, heartbeatMsg)));
SendMessage(clientId, JsonConvert.SerializeObject(heartbeatResponse));
Console.WriteLine($"客户端 {clientId} 心跳检测: {heartbeatModel.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"处理心跳消息失败: {ex.Message}");
}
}
处理未知类型消息
/// <summary>
/// 处理未知类型消息
/// </summary>
private static void HandleUnknownMessage(string clientId, MessageStyle message)
{
try
{
StandMessageModel unknownModel = JsonConvert.DeserializeObject<StandMessageModel>(message.Message);
string responseMsg = $"收到未知类型消息: {unknownModel.Message}";
// 回复发送者
MessageStyle response = new MessageStyle(MessageTypeEnum.Unknown, clientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", clientId, responseMsg)));
SendMessage(clientId, JsonConvert.SerializeObject(response));
}
catch (Exception ex)
{
Console.WriteLine($"处理未知消息失败: {ex.Message}");
}
}
发送消息基础方法
/// <summary>
/// 发送消息
/// </summary>
/// <param name="clientId">目标客户端ID</param>
/// <param name="message">JSON格式的消息字符串</param>
private static void SendMessage(string clientId, string message)
{
try
{
ClientInfo clientInfo;
lock (_lock)
{
if (!_clients.TryGetValue(clientId, out clientInfo))
{
Console.WriteLine($"clientId:{clientId},不存在");
return;
}
}
// 检查Socket是否连接
if (!clientInfo.Socket.Connected)
{
Console.WriteLine($"客户端 {clientId} 已断开,跳过消息发送");
RemoveClient(clientId);
return;
}
// 转为 UTF-8 字节数组
byte[] jsonBytes = Encoding.UTF8.GetBytes(message);
// 获取长度并转换为网络字节序
int length = jsonBytes.Length;
int networkOrderLength = IPAddress.HostToNetworkOrder(length);
byte[] lengthBytes = BitConverter.GetBytes(networkOrderLength);
// 拼接长度+内容
byte[] buffer = new byte[4 + jsonBytes.Length];
Array.Copy(lengthBytes, 0, buffer, 0, 4);
Array.Copy(jsonBytes, 0, buffer, 4, jsonBytes.Length);
// 发送
clientInfo.Socket.Send(buffer);
}
catch (SocketException ex)
{
Console.WriteLine($"向客户端 {clientId} 发送消息失败: 网络异常 {ex.SocketErrorCode} - {ex.Message}");
RemoveClient(clientId);
}
catch (Exception ex)
{
Console.WriteLine($"向客户端 {clientId} 发送消息失败: {ex.Message}");
}
}
在线用户管理
/// <summary>
/// 获取客户端用户名
/// - 无则返回ID
/// </summary>
private static string GetClientName(string clientId)
{
lock (_lock)
{
if (_clients.ContainsKey(clientId) && !string.IsNullOrEmpty(_clients[clientId].ClientName))
{
return _clients[clientId].ClientName;
}
return clientId;
}
}
/// <summary>
/// 处理客户端的在线列表请求
/// </summary>
/// <param name="clientId">请求的客户端ID</param>
private static void HandleListRequest(string clientId)
{
try
{
lock (_lock)
{
// 构建在线列表数据
OnlineListResponseModel listModel = new OnlineListResponseModel
{
TotalCount = _clients.Count,
Users = _clients.Select(c => new OnlineUserModel
{
ClientId = c.Value.ClientId,
UserName = c.Value.ClientName,
LastActiveTime = c.Value.LastActiveTime
}).ToList()
};
// 构建响应消息
MessageStyle responseMsg = new MessageStyle(
MessageTypeEnum.ListRequest,
clientId,
JsonConvert.SerializeObject(listModel)
);
// 发送给请求的客户端
SendMessage(clientId, JsonConvert.SerializeObject(responseMsg));
}
Console.WriteLine($"客户端 {clientId} 请求在线列表,已返回(共{_clients.Count}个在线用户)");
}
catch (Exception ex)
{
Console.WriteLine($"处理在线列表请求失败: {ex.Message}");
// 发送错误提示给客户端
MessageStyle errorMsg = new MessageStyle(
MessageTypeEnum.Text,
clientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", clientId, "获取在线列表失败: " + ex.Message))
);
SendMessage(clientId, JsonConvert.SerializeObject(errorMsg));
}
}
命令行功能实现
/// <summary>
/// 处理控制台输入
/// </summary>
private static void HandleConsoleInput()
{
Console.WriteLine("\n服务器命令:");
DeaultConsoleLine();
while (true)
{
try
{
string input = Console.ReadLine();
if (string.IsNullOrWhiteSpace(input))
continue;
var parts = input.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 0) continue;
string command = parts[0].ToUpper();
string[] args = parts.Length > 1 ? parts.Skip(1).ToArray() : new string[0];
switch (command)
{
case "/EXIT":
Console.WriteLine("正在关闭服务器...");
Environment.Exit(0);
break;
case "/LIST":
Console.WriteLine("当前在线客户端:");
lock (_lock)
{
if (_clients.Count == 0)
{
Console.WriteLine(" 暂无客户端连接");
}
else
{
foreach (var client in _clients)
{
string clientName = string.IsNullOrEmpty(client.Value.ClientName)
? "未设置" : client.Value.ClientName;
Console.WriteLine($" ID: {client.Key} | 用户名: {clientName} | 最后活跃: {client.Value.LastActiveTime:HH:mm:ss}");
}
}
}
break;
case "/MSG":
if (args.Length >= 2)
{
string targetClientId = args[0];
string message = string.Join(" ", args.Skip(1));
// 构建服务器文本消息
MessageStyle serverMsg = new MessageStyle(MessageTypeEnum.Text, targetClientId,
JsonConvert.SerializeObject(new StandMessageModel("SERVER", targetClientId, message)));
SendMessage(targetClientId, JsonConvert.SerializeObject(serverMsg));
Console.WriteLine($"已向 {targetClientId} 发送消息: {message}");
}
else
{
Console.WriteLine("命令格式错误,正确格式: /msg clientId message");
}
break;
case "/BROADCAST":
if (args.Length >= 1)
{
string message = string.Join(" ", args);
MessageStyle broadcastMsg = new MessageStyle(MessageTypeEnum.Broadcast, "SERVER",
JsonConvert.SerializeObject(new StandMessageModel("SERVER", "ALL", message)));
string broadcastJson = JsonConvert.SerializeObject(broadcastMsg);
lock (_lock)
{
foreach (var client in _clients)
{
SendMessage(client.Key, broadcastJson);
}
}
Console.WriteLine($"已广播: {message}");
}
else
{
Console.WriteLine("命令格式错误,正确格式: /broadcast message");
}
break;
case "/HELP":
Console.WriteLine("可用命令:");
DeaultConsoleLine();
break;
default:
Console.WriteLine("未知命令,输入 /help 查看可用命令");
break;
}
}
catch (Exception ex)
{
Console.WriteLine($"处理命令时出错: {ex.Message}");
}
}
}
/// <summary>
/// 默认的命令行提示信息
/// </summary>
private static void DeaultConsoleLine()
{
Console.WriteLine(" /list - 查看在线客户端");
Console.WriteLine(" /msg clientId message - 向指定客户端发送消息");
Console.WriteLine(" /broadcast message - 广播消息");
Console.WriteLine(" /exit - 退出服务器");
Console.WriteLine(" /help - 查看帮助\n");
}
3570

被折叠的 条评论
为什么被折叠?



