当前位置: 首页 > news >正文

TCP 网络编程笔记:TcpListener、TcpClient 与核心用法

TCP 网络编程笔记:TcpListener、TcpClient 与核心用法

一、核心类定位与关系

TCP 网络编程中,TcpListenerTcpClient 是基于 Socket 的高层封装类,三者定位不同但协同实现 TCP 通讯,核心关系如下:

类名核心作用底层依赖适用角色
Socket底层网络通讯基础类,支持 TCP/UDP 等协议直接操作网络底层需精细控制网络细节的场景
TcpListener简化 TCP 服务器端监听逻辑,处理客户端连接请求封装 Socket(TCP 协议)TCP 服务器
TcpClient简化 TCP 客户端连接逻辑,处理数据收发封装 Socket(TCP 协议)TCP 客户端

二、TcpListener 与 TcpClient 核心差异(vs Socket)

对比维度Socket(底层)TcpListener / TcpClient(高层封装)
创建连接需手动指定协议(TCP/UDP)、IP、端口,代码繁琐TcpClient 直接调用 Connect() 建立连接,无需关注底层协议细节
服务器监听需手动调用 Bind() 绑定端口、Listen() 开启监听、Accept() 接收连接TcpListener 直接调用 Start() 开启监听,AcceptTcpClient() 接收连接,流程简化
复杂性需手动处理数据分包 / 组包、错误捕获、缓冲区管理隐藏底层细节,提供 NetworkStream 简化数据读写,开发专注业务逻辑
API 友好度接口偏底层,需理解网络协议细节接口高层化,如 GetStream() 直接获取数据流,降低学习成本

三、核心 API 与使用流程

1. 基础准备:IP 与端口控制(EndPoint 家族)

TCP 通讯需明确 IP 地址和端口,依赖以下类实现:

  • EndPoint:抽象基类,定义网络端点的基本结构。

  • IPEndPointEndPoint 的子类,具体实现 IP 地址(IPAddress)和端口(int)的绑定,格式:new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888)

  • 关键属性:

    • TcpListener.LocalEndpoint:获取 TcpListener(服务器)绑定的本地 IP 和端口。

    • TcpClient.Client.RemoteEndPoint:获取 TcpClient 连接的远程端(服务器 / 客户端)IP 和端口。

    • TcpClient.Client.LocalEndPoint:获取 TcpClient 本地端(客户端 / 服务器)IP 和端口。

2. TcpListener(服务器端)使用流程

步骤 1:实例化 TcpListener

指定监听的 IP 地址和端口,两种方式:

// 方式 1:直接传入 IPAddress 和端口
IPAddress ip = IPAddress.Parse("127.0.0.1"); // 本地回环地址,仅本地访问
int port = 8888;
TcpListener server = new TcpListener(ip, port);
​
// 方式 2:传入 IPEndPoint(更灵活,支持多 IP 绑定)
IPEndPoint endPoint = new IPEndPoint(ip, port);
TcpListener server = new TcpListener(endPoint);
步骤 2:启动监听

调用 Start() 开启服务器监听,等待客户端连接:

server.Start(); // 启动监听,可传入参数限制最大连接数(如 server.Start(10))
Console.WriteLine("服务器已启动,等待客户端连接...");
步骤 3:接收客户端连接

调用 AcceptTcpClient()(阻塞式)或 AcceptTcpClientAsync()(异步)接收连接,返回与客户端通讯的 TcpClient 对象:

// 同步接收(阻塞当前线程)
TcpClient client = server.AcceptTcpClient();
Console.WriteLine($"客户端已连接:{client.Client.RemoteEndPoint}");
​
// 异步接收(推荐,不阻塞线程)
TcpClient client = await server.AcceptTcpClientAsync();
步骤 4:数据读写(通过 NetworkStream)

通过 TcpClient.GetStream() 获取 NetworkStream,实现数据收发:

NetworkStream stream = client.GetStream(); // 获取数据流
​
// 读取客户端数据(需先判断是否有可用数据)
byte[] buffer = new byte[1024]; // 缓冲区(大小根据业务调整)
if (stream.DataAvailable) // 或 client.Available > 0,判断是否有数据
{int readLen = stream.Read(buffer, 0, buffer.Length); // 读取数据到缓冲区string recvMsg = Encoding.UTF8.GetString(buffer, 0, readLen); // 转字符串Console.WriteLine($"收到客户端消息:{recvMsg}");
}
​
// 向客户端发送数据
string sendMsg = "Hello Client!";
byte[] sendBuffer = Encoding.UTF8.GetBytes(sendMsg);
stream.Write(sendBuffer, 0, sendBuffer.Length); // 发送数据
步骤 5:关闭资源

通讯结束后,需释放 NetworkStreamTcpClientTcpListener

stream.Close(); // 关闭数据流
client.Close(); // 关闭与客户端的连接
server.Stop(); // 停止服务器监听(释放端口)

3. TcpClient(客户端)使用流程

步骤 1:实例化 TcpClient

直接创建对象,无需提前指定 IP 和端口:

TcpClient tcpClient = new TcpClient();
步骤 2:连接服务器

调用 Connect()(同步)或 ConnectAsync()(异步)连接服务器:

// 同步连接(阻塞线程)
string serverIp = "127.0.0.1";
int serverPort = 8888;
tcpClient.Connect(serverIp, serverPort);
​
// 异步连接(推荐)
await tcpClient.ConnectAsync(serverIp, serverPort);
Console.WriteLine($"已连接服务器:{tcpClient.Client.RemoteEndPoint}");
步骤 3:数据读写(与服务器端一致)

通过 GetStream() 获取 NetworkStream,实现数据收发,逻辑与服务器端完全相同:

NetworkStream stream = tcpClient.GetStream();
​
// 发送数据到服务器
string sendMsg = "Hello Server!";
byte[] sendBuffer = Encoding.UTF8.GetBytes(sendMsg);
stream.Write(sendBuffer, 0, sendBuffer.Length);
​
// 读取服务器返回数据
byte[] recvBuffer = new byte[1024];
int readLen = stream.Read(recvBuffer, 0, recvBuffer.Length);
string recvMsg = Encoding.UTF8.GetString(recvBuffer, 0, readLen);
Console.WriteLine($"收到服务器消息:{recvMsg}");
步骤 4:关闭资源
stream.Close();
tcpClient.Close();

4. 进阶:异步与取消(Task + CancellationTokenSource)

为避免同步操作阻塞线程,推荐使用异步方法,并通过 CancellationTokenSource(CTS)实现任务取消(如手动关闭连接):

// 创建取消令牌源
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;// 异步接收客户端连接(支持取消)
async Task AcceptClientAsync(TcpListener server)
{while (!token.IsCancellationRequested) // 未取消则持续监听{try{TcpClient client = await server.AcceptTcpClientAsync(token); // 传入取消令牌// 处理客户端通讯(建议开启新线程/任务,避免阻塞监听)_ = HandleClientAsync(client, token);}catch (OperationCanceledException){Console.WriteLine("服务器监听已取消");break;}}
}// 取消任务(如用户点击“关闭服务器”按钮)
cts.Cancel(); // 触发取消,AcceptTcpClientAsync 会抛出 OperationCanceledException

5. 跨线程访问控件(WinForm/WPF)

若在 UI 线程外(如异步接收数据的线程)操作 UI 控件(如 TextBox),需使用 Invoke()BeginInvoke() 切换到 UI 线程:

// WinForm 示例:更新 TextBox 显示收到的消息
private void UpdateTextBox(string msg)
{if (textBox1.InvokeRequired) // 判断是否跨线程{// 跨线程,通过委托调用textBox1.Invoke(new Action<string>(UpdateTextBox), msg);}else{// 同一线程,直接更新textBox1.AppendText(msg + Environment.NewLine);}
}// 在数据接收线程中调用
UpdateTextBox($"收到消息:{recvMsg}");

四、TCP 通讯核心流程(补充)

TCP 是面向连接的可靠协议,完整通讯流程如下(服务器 - 客户端交互):

  1. 服务器启动TcpListener 绑定 IP 和端口 → 调用 Start() 开启监听。

  2. 客户端连接TcpClient 调用 Connect() → 向服务器发送 SYN 报文(TCP 三次握手第一步)。

  3. 三次握手:服务器响应 SYN+ACK 报文 → 客户端响应 ACK 报文 → 连接建立。

  4. 数据交互:双方通过 NetworkStream 读写数据(TCP 保证数据有序、不丢失)。

  5. 连接关闭:一方调用 Close() → 发送 FIN 报文(TCP 四次挥手)→ 双方释放连接。

  6. 服务器停止TcpListener 调用 Stop() → 释放监听端口。

五、关键注意点

  1. 端口占用:若启动 TcpListener 时报 “地址已在使用”,需确认端口是否被其他程序占用(可通过 netstat -ano | findstr "端口号" 查看)。

  2. 数据缓冲区Read() 方法读取的是当前缓冲区中的数据,需根据实际读取长度(readLen)解析数据,避免缓冲区残留旧数据。

  3. 异常处理:需捕获 SocketException(网络错误)、IOException(流操作错误)、OperationCanceledException(任务取消)等异常,保证程序稳定性。

  4. 连接限制TcpListener.Start(int backlog) 中的 backlog 参数指定等待队列的最大长度,超过则新连接会被拒绝,需根据业务需求设置。

http://www.dtcms.com/a/470416.html

相关文章:

  • 群晖的网站开发搜索百度一下
  • 【词根】2025-10-11词根学习
  • 【MFC】项目源码过大,不影响项目设置的打包办法
  • 做聚美优品网站得多少钱wordpress 知更鸟 公告
  • 网站的中英文翻译是怎么做的公司手机网站建设价格
  • 基层建设期刊在哪个网站被收录想做棋牌网站怎么做
  • 商丘网站建设广告ui培训哪里好
  • 微博上如何做网站推广媒介
  • MongoDB 读写分离中 实现强制走主读注解
  • Java-146 深入浅出 MongoDB 数据插入、批量写入、BSON 格式与逻辑查询and or not操作指南
  • EasyExcel实现普通导入导出以及按模板导出excel文件
  • ubuntu 24.10安装MongoDB
  • 开源新经济:Web4.0时代的社区激励模型
  • NXP iMX8MM ARM 平台 Weston RDP 远程桌面部署测试
  • 低代码的系统化演进:从工具逻辑到平台架构的技术解读
  • 告别“时间战“:清北AI原创学习力模型,开启教育效率革命
  • 东莞市电商网站建设做室内概念图的网站
  • PowerShell 递归目录文件名冲突检查脚本(不区分大小写)
  • STM32项目分享:基于STM32的泳池防溺水检测手环
  • 权威解析GEO优化:如何提升品牌在AI搜索中的曝光?
  • C语言与Java语言编译过程及文件类型
  • 基于SpringBoot的农产品(商城)销售系统
  • 有名的网站建设wordpress博客站模板下载
  • 网站打不开如何解决深圳企业网站建设服务中心
  • 专业的论坛网站建设开发wordpress静态化
  • hive的一些优化配置
  • 做网站一屏一屏的盖州网站建设
  • 佳木斯建设工程交易中心网站在龙港网站哪里做
  • 工具收集 - ContextMenuManager 右键管理
  • 【软件设计师中级】计算机组成与结构(六):系统性能评测与可靠性基础 - 衡量计算机的“尺子“与“保险“