TCP 通信协议

TCP 协议简介

TCP 全称传输控制协议,是互联网传输层面向连接、可靠、全双工通信协议,依托 IP 网络传输数据。

  1. 通信前通过三次握手建立连接,传输结束通过四次挥手断开连接;
  2. 依靠确认应答、超时重传、滑动窗口、拥塞控制,保证数据不丢、不乱序、无重复;
  3. 以字节流形式传输数据,一对一通信,牺牲部分速度换取稳定可靠;
  4. 多用于网页、文件、数据库、远程登录等对数据完整性要求高的场景。

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 网络调试工具 作为服务端

相关推荐
清水白石0081 小时前
Python 死锁排查全攻略:从线程卡死到锁依赖定位与工程化修复
linux·网络·python
游戏开发爱好者81 小时前
带签名时间戳接口的重放与压力测试实战,用动态值在发送前现算签名
网络协议·计算机网络·网络安全·ios·adb·https·压力测试
TechWayfarer2 小时前
批量查IP归属地,在线API、脚本、离线库怎么选?三种方案实测对比
网络·python·网络协议·tcp/ip
ryan_9966 小时前
MCP Transport 完整指南:stdio 与 Streamable HTTP 到底怎样传消息
网络·网络协议·http
数据知道8 小时前
网络安全实战:子域名接管实战——从 CNAME 配置错误到完全控制
网络·安全·web安全·网络安全
lf13210279 小时前
用 JSON Schema 管装修节点记录:从照片台账到可校验工程数据
网络·数据库·人工智能·经验分享·物联网·json·智能家居
LayZhangStrive9 小时前
后端通识 - 远程服务调用RPC
网络·网络协议·rpc·sentinel·openfeign·远程服务调用
华清远见成都中心10 小时前
FreeRTOS事件组(Event Group)的工作机制分析
服务器·网络·网络协议
xiaoxiangsiyan11 小时前
RHCE2026云原生路线EX188和EX288完整备考指南
运维·网络·云原生·自动化
西安景驰电子11 小时前
《PTP精确时间协议系列》第二篇:工程部署、调试与性能优化
运维·服务器·网络·数据库·windows·性能优化