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格式错误处理

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

相关推荐
Bdygsl2 小时前
数据结构 —— 顺序表
数据结构·链表
重生之我在番茄自学网安拯救世界2 小时前
网络安全中级阶段学习笔记(十二):PHP 文件包含漏洞全解析(原理 + 利用 + 防御 )
笔记·学习·web安全·文件包含漏洞·网安基础
走在路上的菜鸟2 小时前
Android学Dart学习笔记第二十四节 类-可调用对象Class()()
android·笔记·学习·flutter
CodeCraft Studio2 小时前
Excel处理控件Aspose.Cells教程:使用C#在Excel中创建气泡图
信息可视化·c#·excel·aspose·excel api库·excel气泡图·excel组件库
HAREWORK_FFF2 小时前
北京一隅:我的CAIE认证报考与学习手记
学习
鲨莎分不晴2 小时前
独立学习 (IQL):大道至简还是掩耳盗铃
人工智能·深度学习·学习
(❁´◡`❁)Jimmy(❁´◡`❁)2 小时前
F - Manhattan Christmas Tree 2
数据结构·算法
良木生香2 小时前
【数据结构-初阶】顺序表相关习题
数据结构
鲨莎分不晴2 小时前
从 10 到 1000:大规模多智能体的可扩展性 (Mean Field & GNN)
人工智能·学习