TCP 协议简介
TCP 全称传输控制协议,是互联网传输层面向连接、可靠、全双工通信协议,依托 IP 网络传输数据。
- 通信前通过三次握手建立连接,传输结束通过四次挥手断开连接;
- 依靠确认应答、超时重传、滑动窗口、拥塞控制,保证数据不丢、不乱序、无重复;
- 以字节流形式传输数据,一对一通信,牺牲部分速度换取稳定可靠;
- 多用于网页、文件、数据库、远程登录等对数据完整性要求高的场景。
TCP 客户端
c# 代码
cs
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace TestTcp
{
internal class Program
{
// TCP客户端实例,用于建立和管理与服务器的连接
static TcpClient client = null;
// 网络流对象,用于读写数据
static NetworkStream stream = null;
// 控制循环运行的标志位,设为false时停止运行
static bool running = true;
// 程序入口点
public static void Main(string[] args)
{
Console.Title = "TCP客户端"; // 设置控制台窗口标题
TestTcpClient(); // 启动TCP客户端
}
// TCP客户端主方法 - 建立连接并处理交互
// 功能:连接服务器、启动接收线程、循环读取用户输入并发送
public static void TestTcpClient()
{
try
{
// 创建TCP客户端实例
client = new TcpClient();
// 连接到本地服务器,端口10020
client.Connect("127.0.0.1", 10020);
// 获取网络流,用于后续的数据读写操作
stream = client.GetStream();
Console.WriteLine("已连接到服务器 127.0.0.1:10020");
// 创建接收数据的后台线程
Thread recvThread = new Thread(ReceiveData);
// 设置为后台线程,主线程结束时自动结束
recvThread.IsBackground = true;
// 启动接收线程,开始监听服务器消息
recvThread.Start();
// 主循环:持续读取用户输入并发送到服务器
while (running)
{
// 从控制台读取一行用户输入
string input = Console.ReadLine();
if (input == null) continue; // 输入为空则跳过
if (input.ToLower() == "exit") // 用户输入exit时退出
{
running = false; // 设置标志停止运行
break; // 跳出循环
}
// 检查流是否可写(防止连接断开)
if (stream != null && stream.CanWrite)
{
// 将字符串转换为UTF-8字节数组
byte[] data = Encoding.UTF8.GetBytes(input);
// 通过网络流发送数据到服务器
stream.Write(data, 0, data.Length);
}
}
}
// 捕获Socket相关异常(如连接失败、网络中断等)
catch (SocketException ex)
{
Console.WriteLine("连接失败: " + ex.Message);
}
// 捕获其他未预期的异常
catch (Exception ex)
{
Console.WriteLine("错误: " + ex.Message);
}
// finally块确保资源被正确释放
finally
{
running = false; // 停止所有运行中的操作
if (stream != null) stream.Close(); // 关闭网络流
if (client != null) client.Close(); // 关闭TCP连接
Console.WriteLine("已断开连接");
}
}
// 接收数据的方法 - 在后台线程中运行
// 功能:持续监听服务器发来的数据并显示在控制台
static void ReceiveData()
{
try
{
// 创建缓冲区用于存储接收到的数据(最大1024字节)
byte[] buffer = new byte[1024];
// 循环接收数据,直到程序停止或连接断开
while (running && stream != null)
{
// 检查是否有数据可读(非阻塞方式)
if (stream.DataAvailable)
{
// 从流中读取数据到缓冲区
int bytesRec = stream.Read(buffer, 0, buffer.Length);
// 如果接收到0字节,表示服务器关闭了连接
if (bytesRec == 0)
{
Console.WriteLine("服务器断开连接");
running = false; // 设置标志停止主循环
break; // 跳出接收循环
}
// 将字节数据转换为UTF-8字符串
string msg = Encoding.UTF8.GetString(buffer, 0, bytesRec);
// 显示服务器发来的消息
Console.WriteLine("[服务器] " + msg);
}
// 短暂休眠避免CPU占用过高
Thread.Sleep(100);
}
}
catch (Exception)
{
// 仅在正常运行状态下提示异常(退出时不显示)
if (running)
{
Console.WriteLine("接收数据异常,连接已断开");
running = false; // 停止主循环
}
}
}
}
}
数据流向图

TCP UDP 网络调试工具 作为服务端

服务端
c# 代码
cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace TestTcpServer
{
internal class Program
{
// TCP监听器,用于接受客户端连接
static TcpListener listener = null;
// 与客户端通信的TCP客户端实例
static TcpClient client = null;
// 网络流对象,用于读写数据
static NetworkStream stream = null;
// 控制循环运行的标志位,设为false时停止运行
static bool running = true;
// 程序入口点
public static void Main(string[] args)
{
Console.Title = "TCP服务端"; // 设置控制台窗口标题
StartServer(); // 启动TCP服务端
}
// TCP服务端主方法 - 监听连接并处理交互
// 功能:监听端口、接受连接、启动接收线程、循环读取用户输入并发送
public static void StartServer()
{
try
{
// 创建TCP监听器,绑定本地IP和端口10021,可根据需要修改
listener = new TcpListener(IPAddress.Any, 10021);
// 开始监听
listener.Start();
Console.WriteLine("服务端已启动,监听端口 10021,等待客户端连接...");
// 等待客户端连接(阻塞)
client = listener.AcceptTcpClient();
// 获取与客户端通信的网络流
stream = client.GetStream();
Console.WriteLine("客户端已连接: " + client.Client.RemoteEndPoint);
// 创建接收数据的后台线程
Thread recvThread = new Thread(ReceiveData);
// 设置为后台线程,主线程结束时自动结束
recvThread.IsBackground = true;
// 启动接收线程,开始监听客户端消息
recvThread.Start();
// 主循环:持续读取用户输入并发送到客户端
while (running)
{
// 从控制台读取一行用户输入
string input = Console.ReadLine();
if (input == null) continue; // 输入为空则跳过
if (input.ToLower() == "exit") // 用户输入exit时退出
{
running = false; // 设置标志停止运行
break; // 跳出循环
}
// 检查流是否可写(防止连接断开)
if (stream != null && stream.CanWrite)
{
// 将字符串转换为UTF-8字节数组
byte[] data = Encoding.UTF8.GetBytes(input);
// 通过网络流发送数据到客户端
stream.Write(data, 0, data.Length);
}
}
}
// 捕获Socket相关异常(如端口占用、网络中断等)
catch (SocketException ex)
{
Console.WriteLine("Socket异常: " + ex.Message);
}
// 捕获其他未预期的异常
catch (Exception ex)
{
Console.WriteLine("错误: " + ex.Message);
}
// finally块确保资源被正确释放
finally
{
running = false; // 停止所有运行中的操作
if (stream != null) stream.Close(); // 关闭网络流
if (client != null) client.Close(); // 关闭客户端连接
if (listener != null) listener.Stop(); // 停止监听
Console.WriteLine("服务端已关闭");
}
}
// 接收数据的方法 - 在后台线程中运行
// 功能:持续监听客户端发来的数据并显示在控制台
static void ReceiveData()
{
try
{
// 创建缓冲区用于存储接收到的数据(最大1024字节)
byte[] buffer = new byte[1024];
// 循环接收数据,直到程序停止或连接断开
while (running && stream != null)
{
// 检查是否有数据可读(非阻塞方式)
if (stream.DataAvailable)
{
// 从流中读取数据到缓冲区
int bytesRec = stream.Read(buffer, 0, buffer.Length);
// 如果接收到0字节,表示客户端关闭了连接
if (bytesRec == 0)
{
Console.WriteLine("客户端断开连接");
running = false; // 设置标志停止主循环
break; // 跳出接收循环
}
// 将字节数据转换为UTF-8字符串
string msg = Encoding.UTF8.GetString(buffer, 0, bytesRec);
// 显示客户端发来的消息
Console.WriteLine("[客户端] " + msg);
}
// 短暂休眠避免CPU占用过高
Thread.Sleep(100);
}
}
catch (Exception)
{
// 仅在正常运行状态下提示异常(退出时不显示)
if (running)
{
Console.WriteLine("接收数据异常,连接已断开");
running = false; // 停止主循环
}
}
}
}
}
完整通信流程图


TCP UDP 网络调试工具 作为服务端
