C# 基于 Socket 实现以太网 TCP 服务器

云舒
云舒
发布时间:2026-10-15 | 5人浏览过
原创

本文介绍如何在 C# 环境中通过底层 Socket API 搭建一个支持多客户端连接的以太网 TCP 服务器。内容包含从对象声明、IP 端口绑定到开启监听及处理数据收发的核心代码逻辑。

基础引用与类结构

在 C# 项目中实现以太网通信,首先需要引入 System.Net.Sockets 命名空间。该命名空间提供了构建网络应用所需的基类。为了明确代码意图,建议采用具有描述性的变量命名方式:

  • socketSever:作为服务端的主 Socket 对象,既可用于绑定和监听,也代表整个服务实例。
  • TcpListener:.NET 提供的更高级别的 TCP 监听类,若需简化开发可替代直接使用 Socket。
  • TcpClient:用于表示已连接的客户端实例。

Socket 构造函数与参数定义

创建 Socket 实例时,必须指定三个关键参数:AddressFamily(地址族)、SocketType(套接字类型)和 ProtocolType(协议类型)。对于标准的以太网 TCP 服务,组合通常为 IPv4、流式套接字和 TCP 协议。

1. 地址族 (AddressFamily)

地址族决定了 Socket 将使用的寻址方案。以太网场景下主要关注以下枚举值:

public enum AddressFamily {
    InterNetwork = 2,   // IPv4 地址,最常用
    InterNetworkV6 = 23,// IPv6 地址
    Unknown = -1        // 未知地址族
}

2. 套接字类型 (SocketType)

定义了通信的信道特征。TCP 依赖可靠的双向数据流,因此选择 Stream:

public enum SocketType {
    Stream = 1, // 面向连接、可靠的字节流(TCP 使用)
    Dgram = 2,  // 数据报,无连接(UDP 使用)
    Raw = 3     // 原始套接字,常用于底层抓包或 ICMP
}

3. 协议类型 (ProtocolType)

指定在套接字之上使用的具体协议。对于 IP 版本 4 的 TCP 传输,固定使用 Tcp:

public enum ProtocolType {
    Tcp = 6,
    Udp = 17,
    IP = 0,
    Icmp = 1
}

服务端初始化与绑定操作

完成对象声明后,需按顺序执行绑定、监听和启动后台任务三个步骤,使服务器进入就绪状态。

第 1 步:实例化 Socket 对象

根据前述参数创建一个负责监听的 Socket 实例。注意 Socket 构造函数没有无参选项,必须传入上述组合。

// 声明服务对象
private Socket socketSever;

// 初始化:IPv4 + 流式 TCP
socketSever = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

第 2 步:绑定本地端点 (Bind)

创建一个 IPEndPoint 对象,指定服务器监听的 IP 地址和端口号,并将其绑定到 Socket 上。绑定失败通常意味着端口被占用或权限不足。

IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("192.168.0.7"), 12345);
try 
{
    socketSever.Bind(ipe);
} 
catch (Exception ex) 
{
    MessageBox.Show("服务器开启失败:" + ex.Message);
    return;
}

第 3 步:开启监听 (Listen)

调用 Listen 方法并设置 backlog 参数,系统将为未处理的连接请求建立队列,防止客户端过多导致连接拒绝。

// 同时排队等待接受连接的数量
socketSever.Listen(10);

// 按钮状态更新
buttonStartService.Enabled = false;

第 4 步:启动后台接收线程

监听必须在非 UI 线程中运行,否则会阻塞界面。使用 Task.Run 启动新线程执行循环监听逻辑。

Task.Run(new Action(() => 
{
    AcceptClients(); // 进入接受连接循环
}));

处理客户端连接与数据收发

服务端启动后,需要持续监听新连接的到来,并为每个已连接客户端分配独立的线程处理数据读写,以实现并发支持。

第 5 步:接受客户端连接 (Accept)

在 while 循环中调用 Accept 方法。该方法会阻塞直到有新连接请求。返回的 Socket 实例代表与该特定客户端的通道。

private void AcceptClients()
{
    while (true)
    {
        // 阻塞等待客户端连接
        Socket socketClient = socketSever.Accept();
        
        string clientIP = socketClient.RemoteEndPoint.ToString();
        
        // 假设存在管理连接的集合
        clientPhoneBook.Add(clientIP, socketClient);
        UpdateConnectionStatus(clientIP, true);
        
        // 为每个客户端开启单独的接收线程
        Task.Run(new Action(() => 
        {
            ReceiveData(socketClient);
        }));
    }
}

第 6 步:读取客户端数据 (Receive)

在每个客户端专属线程中,创建足够大的缓冲区(byte[])并使用 Receive 方法读取数据。需注意处理异常以判断客户端是否离线。

private void ReceiveData(Socket socketClient)
{
    while (true)
    {
        byte[] buffer = new byte[1024 * 1024 * 10]; // 示例大缓冲区
        int length = -1;
        string client = socketClient.RemoteEndPoint.ToString();

        try 
        {
            // 阻塞读取数据
            length = socketClient.Receive(buffer);
        } 
        catch (Exception) 
        {
            // 捕获到异常通常意味着对端断开连接
            HandleClientDisconnect(client);
            break;
        }

        if (length > 0)
        {
            // 成功读取数据,进行解码处理
            string message = Encoding.UTF8.GetString(buffer, 0, length);
            ProcessMessage(client, message);
        } 
        else 
        {
            // length 为 0 表示正常关闭连接
            HandleClientDisconnect(client);
        }
    }
}

// 辅助方法:处理断开逻辑
private void HandleClientDisconnect(string clientIP)
{
    UpdateConnectionStatus(clientIP, false);
    clientPhoneBook.Remove(clientIP);
}

总结

C# 中的 Socket 网络编程核心在于理解地址族、类型与协议的对应关系,并通过 Bind、Listen、Accept 构建服务器骨架。结合多线程处理单个客户端的数据收发,可以构建出稳定且具备一定并发能力的以太网通信服务。以上就是 C# 以太网 Socket 服务器设计与实现的详细内容,更多关于 C# Socket 开发的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表