如何在C#中基于Socket编程实现客户端服务端架构并向客户端传递数据库数据
整体基础设施分层定义
1. 服务端核心模块
- 监听模块:基于
.NET Framework内置的TcpListener类实现,监听端口固定为非系统占用端口(建议选1024以上的未被占用端口,例如9876)。因最大仅需接入2-3台客户端,无需使用高并发IOCP模型,采用简单多线程处理连接即可:每接入一个新客户端就开启独立后台线程处理该客户端的所有请求,不会阻塞监听主线程。 - 数据库访问模块:用.NET Framework内置的数据库操作类实现,对接SQL Server托管库用
System.Data.SqlClient,对接其他类型托管库可适配System.Data.OleDb。数据库连接字符串存放在服务端App.config的<connectionStrings>节点,仅封装客户端需要的查询接口,禁止直接执行客户端传入的SQL语句,避免注入风险。 - 报文解析模块:自定义简单的请求/响应报文格式解决粘包问题,规则如下:报文前4位固定为Int32类型的报文总长度,后续内容为结构化数据。序列化/反序列化用.NET内置的
System.Web.Script.Serialization.JavaScriptSerializer实现,无需引入第三方JSON库。请求报文中携带设备标识、请求数据类型;响应报文中携带响应状态码、查询结果数据集。 - 权限校验模块:客户端首次发起连接时需要传输预设的设备唯一标识,服务端校验通过后才处理后续请求,避免非法设备接入。
2. 客户端核心模块
- 连接模块:基于内置的
TcpClient类实现,设备开机后自动启动连接逻辑,配置3次重试机制,每次重试间隔5秒,连接失败写入本地日志。 - 请求生成模块:按服务端约定的报文格式生成数据请求报文,携带本机设备标识和需要拉取的数据类型。
- 响应解析模块:收到服务端返回的报文后按约定格式解析,解析成功后将数据持久化到本地存储,可选择.NET内置的
System.Xml操作XML文件存储,也可用内置的SQLite接口存储,数据供本地业务逻辑直接调用。 - 异常处理模块:出现连接断开、报文解析失败等异常时自动重试,重试失败写入本地错误日志,不阻塞设备其他开机流程。
3. 部署与运行规则
- 服务端部署在和托管数据库同内网的机器上,防火墙开放指定监听端口,仅允许2-3台客户端的固定IP访问该端口,进一步降低安全风险。
- 服务端做成Windows服务,开机自动启动,配置异常退出自动重启策略,用
.NET Framework内置的ServiceBase类实现即可,无需第三方服务框架。 - 客户端做成开机自启的后台进程,无需UI,完成数据拉取后可自动退出,也可保持后台轻量连接按需拉取其他数据。
4. 核心代码示例
服务端监听核心代码
// 初始化监听 TcpListener listener = new TcpListener(IPAddress.Any, 9876); listener.Start(); while (true) { TcpClient client = listener.AcceptTcpClient(); // 每个客户端分配独立线程处理请求 Thread clientThread = new Thread(ProcessClientRequest); clientThread.IsBackground = true; clientThread.Start(client); }
客户端连接核心代码
using (TcpClient client = new TcpClient()) { client.Connect("服务端内网IP", 9876); NetworkStream stream = client.GetStream(); // 构造并发送请求报文 byte[] requestBuffer = BuildRequestPacket(); stream.Write(requestBuffer, 0, requestBuffer.Length); // 接收并解析响应报文 byte[] responseBuffer = new byte[1024 * 1024]; // 可根据实际数据大小调整 int readLength = stream.Read(responseBuffer, 0, responseBuffer.Length); ParseResponsePacket(responseBuffer, readLength); }
内容的提问来源于stack exchange,提问作者Satyajit Das
相关产品推荐
相关产品推荐

