c#Socket学习,使用Socket创建一个在线聊天,需求分析与创建项目,数据结构创建(1)

CSharp Socket学习 - 需求分析与创建项目

使用控制台实现服务端和客户端,操作使用命令实现。不使用数据库,尽量不使用第三方插件。

项目初始化

服务端项目:.NET Framework 控制台应用程序

修改项目名称和解决方案 名称

项目名称:Socket_Study_Server

解决方案名称:Socket_Study_OnClieChat

客户端项目:.NET Framework 控制台应用程序

客户端名:Socket_Study_Client

解决方案名称:Socket_Study_OnClieChat

数据结构项目:.NET Framework 类库

名称:Socket_Study_Model

解决方案名称:Socket_Study_OnClieChat

最后创建完毕

第三方引用:Newtonsoft.Json (JSON序列化库)

功能设计

客户端连接

• 客户端标识:使用GUID生成唯一客户端ID

csharp 复制代码
        /// <summary>
        /// 生成客户端ID
        /// </summary>
        static string GenerateClientId()
        {
            lock (_lock)
            {
                return $"CLIENT_{Guid.NewGuid():N}";
            }
        }

• 客户端信息存储:ClientInfo类存储Socket、ID、用户名、活跃时间

csharp 复制代码
using System;
using System.Net.Sockets;

namespace Socket_Study_Pro
{
    /// <summary>
    /// 客户端信息类
    /// </summary>
    public class ClientInfo
    {
        /// <summary>
        /// 客户端id
        /// </summary>
        public string ClientId { get; set; }

        /// <summary>
        /// 客户端的用户名
        /// </summary>
        public string ClientName { get; set; }

        /// <summary>
        /// socket
        /// </summary>
        public Socket Socket { get; set; }

        /// <summary>
        /// 最后上线时间
        /// </summary>
        public DateTime LastActiveTime { get; set; }

        /// <summary>
        /// 是否链接
        /// </summary>
        public bool IsConnected { get; set; }
    }
}

• 线程安全的字典:使用锁机制管理客户端列表

复制代码
        /// <summary>
        /// 客户端列表
        /// </summary>
        private static Dictionary<string, ClientInfo> _clients = new Dictionary<string, ClientInfo>();

        /// <summary>
        /// 线程锁
        /// </summary>
        private static object _lock = new object();

• 连接状态维护:IsConnected标志位跟踪连接状态

消息协议设计

• 消息头格式:4字节长度标识 + JSON消息体,这样后期也可以发送图片或者文件,4字节长度标识可以发送4GB大小的数据

复制代码
0xFF 0xFF 0xFF 0xFF {JSON}

• 消息类型:Welcome, Text, Broadcast, PrivateMsg, SetUserName, Heartbeat, ListRequest, Unknown

csharp 复制代码
namespace Socket_Study_Entity
{
    /// <summary>
    /// 消息类型枚举
    /// </summary>
    public enum MessageTypeEnum
    {
        /// <summary>
        /// 未知类型
        /// </summary>
        Unknown = 0,

        /// <summary>
        /// 欢迎消息
        /// </summary>
        Welcome = 1,

        /// <summary>
        /// 普通文本消息
        /// </summary>
        Text = 2,

        /// <summary>
        /// 广播消息
        /// </summary>
        Broadcast = 3,

        /// <summary>
        /// 心跳消息
        /// </summary>
        Heartbeat = 4,

        /// <summary>
        /// 隐私消息
        /// </summary>
        PrivateMsg = 5,

        /// <summary>
        /// 设置自己的用户名
        /// </summary>
        SetUserName = 6,

        /// <summary>
        /// 获取用户列表
        /// </summary>
        ListRequest = 7,
    }
}

消息处理

先创建可能用到的方法,后续进行补充。

• 欢迎消息处理:连接时发送欢迎消息和客户端ID, private static void SendWelcomeMessage(string clientId)

• 文本消息处理:普通文本消息的收发 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)

• 心跳检测:保持连接活跃,检测客户端在线状态,private static void HandleHeartbeatMessage(string clientId, MessageStyle message)

• 在线列表查询:客户端可查询当前所有在线用户,private static void HandleListRequest(string clientId)

• 消息格式验证:JSON反序列化验证和异常处理,private static void HandleUnknownMessage(string clientId, MessageStyle message)

消息传输

• 消息分包处理:基于长度的消息完整接收

• 缓冲区管理:复用缓冲区减少内存分配

• 流式读取:使用MemoryStream累积消息数据

• 可靠发送:带长度信息的可靠消息发送

• 连接状态检测:发送前检查Socket连接状态

客户端会话

• 客户端心跳:通过心跳消息维持连接

• 活跃时间更新:每次消息收发更新最后活跃时间

服务器控制台

• 命令行:控制台输入命令解析

• 在线客户端列表:查看所有连接的客户端信息

• 定向消息发送:服务器向指定客户端发送消息

• 服务器广播:服务器向所有客户端广播消息

• 服务器关闭:安全关闭服务器的命令

• 帮助:显示可用命令列表

数据结构

消息模型,需要在Socket_Study_Model 中创建

• MessageStyle:消息基础结构,所有的消息都要被包裹,赋值给message字段

csharp 复制代码
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Socket_Study_Model 
{
    /// <summary>
    /// 消息基础格式
    /// </summary>
    public class MessageStyle
    {
        /// <summary>
        /// 消息类型
        /// </summary>
        [JsonConverter(typeof(StringEnumConverter))]
        public MessageTypeEnum Type { get; set; } = MessageTypeEnum.Unknown;

        /// <summary>
        /// 发送方的clientid
        /// </summary>
        public string ClientId { get; set; }

        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }


        public MessageStyle(MessageTypeEnum messageTypeEnum, string clientId, string message)
        {
            Type = messageTypeEnum;
            ClientId = clientId;
            Message = message;
        }

    }
}

• StandMessageModel:标准消息模型,通用的消息模型

csharp 复制代码
using System;

namespace Socket_Study_Model
{
    /// <summary>
    /// 标准消息模型
    /// </summary>
    [Serializable]
    public class StandMessageModel
    {

        /// <summary>
        /// 发送方clientid
        /// </summary>
        public string SenderClientId;

        /// <summary>
        /// 发送方id
        /// </summary>
        public string SenderName;

        /// <summary>
        /// 目标clientid
        /// </summary>
        public string TargetClientID;

        /// <summary>
        /// 发送方名称
        /// </summary>
        public string TargetName;

        /// <summary>
        /// 消息
        /// </summary>
        public string Message;

        /// <summary>
        /// 构建消息
        /// </summary>
        /// <param name="senderClientId">发送方id</param>
        /// <param name="targetClientID">目标id</param>
        /// <param name="message">消息内容</param>
        public StandMessageModel(string senderClientId, string targetClientID, string message)
        {
            SenderClientId = senderClientId;
            TargetClientID = targetClientID;
            Message = message;
        }
    }
}

• WelComMessageModel:欢迎消息模型

csharp 复制代码
using System;

namespace Socket_Study_Entity
{
    /// <summary>
    /// 欢迎消息的model
    /// </summary>
    [Serializable]
    public class WelComMessageModel
    {
        /// <summary>
        /// 欢迎消息
        /// </summary>
        public string Message;

        public WelComMessageModel(string message)
        {
            Message = message;
        }

    }
}

• OnlineListResponseModel:在线列表响应模型,OnlineUserModel:在线用户信息模型

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Socket_Study_Model
{
    /// <summary>
    /// 在线用户信息模型
    /// </summary>
    public class OnlineUserModel
    {
        /// <summary>
        /// 客户端ID
        /// </summary>
        public string ClientId { get; set; }

        /// <summary>
        /// 用户名(未设置则显示"未命名")
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 最后活跃时间
        /// </summary>
        public DateTime LastActiveTime { get; set; }
    }

    /// <summary>
    /// 在线列表响应模型
    /// </summary>
    public class OnlineListResponseModel
    {
        /// <summary>
        /// 在线用户总数
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// 在线用户列表
        /// </summary>
        public List<OnlineUserModel> Users { get; set; } = new List<OnlineUserModel>();
    }
}

客户端信息

• ClientInfo:包含Socket、ID、用户名、最后活跃时间、连接状态

• 线程安全存储:使用锁保护的字典存储客户端信息

网络异常处理

• Socket异常:连接重置、连接中止、超时等

• IO异常:读写操作异常

• 序列化异常:JSON格式错误处理

• 线程安全异常:并发访问控制

相关推荐
驱动探索者11 分钟前
linux mailbox 学习
linux·学习·算法
进阶小白猿16 分钟前
Java技术八股学习Day33
java·开发语言·学习
收菜福星17 分钟前
当AI Agent成为大学标配:2026年学习模式的深层变革
人工智能·学习
程序员敲代码吗22 分钟前
如何通过命令行启动COMSOL的参数化、批处理和集群扫描
java·c#·bash
蒟蒻的贤28 分钟前
yolo12结构学习
学习
历程里程碑1 小时前
普通数组----合并区间
java·数据结构·python·算法·leetcode·职场和发展·tornado
●VON1 小时前
CANN推理引擎:从云端到边缘的极致加速与部署实战
学习·react native
笔画人生1 小时前
深度解析 CANN 项目:以 `ops-transformer` 为例探索高性能 AI 算子库
学习·开源
梵刹古音2 小时前
【C语言】 指针与数据结构操作
c语言·数据结构·算法
AI视觉网奇2 小时前
3d数字人 ue blender 绑定衣服对齐 2026
学习·ue5