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

Delphi 网络编程实战:TIdTCPClient 与 TIdTCPServer 类深度解析

在 Delphi 开发中,网络通信是桌面应用、服务端程序、物联网设备交互的核心需求。Indy(Internet Direct)组件库是 Delphi 内置的老牌网络开发工具包,基于阻塞式套接字实现,封装了 TCP、UDP、HTTP 等主流网络协议,其中TIdTCPClient(TCP 客户端)TIdTCPServer(TCP 服务端)是实现自定义 TCP 通信的核心类,也是 Delphi 网络编程的基础。

本文将从零讲解这两个核心类的用法、关键属性 / 方法、线程安全机制,并提供完整的客户端 + 服务端通信实战代码。

一、Indy 组件库基础

Indy 是 Delphi 自带的跨平台网络组件库,无需额外安装,直接在组件面板的Indy ClientsIndy Servers分类中调用:

  • TIdTCPClient:客户端组件,用于主动连接服务端、发送 / 接收数据;
  • TIdTCPServer:服务端组件,用于监听端口、接受客户端连接、处理多客户端通信;
  • 核心特性:阻塞式通信(数据收发时会阻塞当前线程,需配合线程避免界面卡死)、支持多客户端连接、内置数据编码 / 解码、异常捕获机制。

适用场景:自定义协议通信、设备控制、内网数据传输、服务端监听等。

二、TIdTCPClient 客户端核心详解

1. 关键属性

表格

属性名作用
Host目标服务端的 IP 地址(如127.0.0.1本地回环、192.168.1.100内网 IP)
Port目标服务端的监听端口(需与服务端一致,范围 1~65535)
Connected只读属性,判断是否与服务端建立连接(True = 已连接,False = 未连接)
ReadTimeout数据读取超时时间(毫秒),避免无限阻塞

2. 核心方法

  • Connect:主动连接服务端,失败会抛出异常(需用try...except捕获);
  • Disconnect:断开与服务端的连接,释放套接字资源;
  • IOHandler.Write:发送数据(支持字符串、字节流、整数等类型);
  • IOHandler.ReadString:读取指定长度的字符串数据;
  • IOHandler.ReadLn:按行读取数据(以换行符\n为结束标记)。

三、TIdTCPServer 服务端核心详解

1. 关键属性

表格

属性名作用
DefaultPort服务端监听的端口(客户端需通过此端口连接)
Active启动 / 停止服务端(True = 启动监听,False = 停止监听)
Bindings绑定监听的 IP(默认 0.0.0.0 监听所有网卡,可指定内网 IP)
Contexts存储所有已连接的客户端上下文(用于遍历在线客户端)

2. 核心事件(服务端核心逻辑)

  • OnConnect:客户端成功连接时触发,可记录客户端信息;
  • OnDisconnect:客户端断开连接时触发,清理资源;
  • OnExecute核心事件,客户端发送数据时触发,用于接收 / 处理数据、回复客户端;
  • OnException:捕获通信过程中的异常,避免服务端崩溃。

3. 线程安全机制

TIdTCPServer 内置多线程管理:每一个客户端连接都会分配一个独立线程(TIdContext),所有客户端通信互不干扰,无需手动创建线程,这是 Indy 最实用的特性。

四、实战:Delphi TCP 客户端 + 服务端完整实现

环境准备

  • Delphi 7/XE/10.X 版本(本文以 Delphi 10.4 为例);
  • 新建两个 VCL 工程:TCPClientDemo(客户端)TCPServerDemo(服务端)

第一部分:服务端开发(TCPServerDemo)

1. 界面设计
  • 1 个TMemo(名称:memoLog,显示日志);
  • 2 个TButton(btnStart = 启动服务,btnStop = 停止服务);
  • 1 个TIdTCPServer(名称:IdTCPServer1,拖入界面即可)。
2. 完整代码

delphi

unit ServerMain; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.IdTCPServer, IdContext, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPServer; type TForm1 = class(TForm) IdTCPServer1: TIdTCPServer; memoLog: TMemo; btnStart: TButton; btnStop: TButton; procedure btnStartClick(Sender: TObject); procedure btnStopClick(Sender: TObject); procedure IdTCPServer1Connect(AContext: TIdContext); procedure IdTCPServer1Disconnect(AContext: TIdContext); procedure IdTCPServer1Execute(AContext: TIdContext); procedure IdTCPServer1Exception(AContext: TIdContext; AException: Exception); private { Private declarations } procedure Log(Msg: string); // 日志输出方法 public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} // 日志输出(线程安全,避免界面卡死) procedure TForm1.Log(Msg: string); begin TThread.Synchronize(nil, procedure begin memoLog.Lines.Add(FormatDateTime('yyyy-mm-dd hh:MM:ss', Now) + ':' + Msg); end); end; // 启动服务 procedure TForm1.btnStartClick(Sender: TObject); begin if IdTCPServer1.Active then Exit; IdTCPServer1.DefaultPort := 8888; // 监听端口8888 IdTCPServer1.Active := True; Log('服务已启动,监听端口:8888'); end; // 停止服务 procedure TForm1.btnStopClick(Sender: TObject); begin IdTCPServer1.Active := False; Log('服务已停止'); end; // 客户端连接事件 procedure TForm1.IdTCPServer1Connect(AContext: TIdContext); var ClientIP: string; begin // 获取客户端IP和端口 ClientIP := AContext.Binding.PeerIP + ':' + IntToStr(AContext.Binding.PeerPort); Log('客户端连接:' + ClientIP); end; // 客户端断开事件 procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext); var ClientIP: string; begin ClientIP := AContext.Binding.PeerIP + ':' + IntToStr(AContext.Binding.PeerPort); Log('客户端断开:' + ClientIP); end; // 核心:接收客户端数据并回复 procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); var RecvStr: string; ClientIP: string; begin // 按行读取客户端发送的数据 RecvStr := AContext.Connection.IOHandler.ReadLn; ClientIP := AContext.Binding.PeerIP; Log('收到['+ClientIP+']数据:' + RecvStr); // 回复客户端 AContext.Connection.IOHandler.WriteLn('服务端已收到:' + RecvStr); end; // 异常捕获 procedure TForm1.IdTCPServer1Exception(AContext: TIdContext; AException: Exception); begin Log('通信异常:' + AException.Message); end; end.

第二部分:客户端开发(TCPClientDemo)

1. 界面设计
  • 1 个TMemo(memoLog,显示通信日志);
  • 1 个TEdit(edtSend,输入发送内容);
  • 3 个TButton(btnConnect = 连接服务端,btnSend = 发送数据,btnDisconnect = 断开连接);
  • 1 个TIdTCPClient(IdTCPClient1,拖入界面)。
2. 完整代码

delphi

unit ClientMain; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient; type TForm1 = class(TForm) IdTCPClient1: TIdTCPClient; memoLog: TMemo; edtSend: TEdit; btnConnect: TButton; btnSend: TButton; btnDisconnect: TButton; procedure btnConnectClick(Sender: TObject); procedure btnSendClick(Sender: TObject); procedure btnDisconnectClick(Sender: TObject); private { Private declarations } procedure Log(Msg: string); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} // 日志输出 procedure TForm1.Log(Msg: string); begin memoLog.Lines.Add(FormatDateTime('yyyy-mm-dd hh:MM:ss', Now) + ':' + Msg); end; // 连接服务端 procedure TForm1.btnConnectClick(Sender: TObject); begin if IdTCPClient1.Connected then Exit; try IdTCPClient1.Host := '127.0.0.1'; // 服务端IP(本地测试用回环地址) IdTCPClient1.Port := 8888; // 服务端端口 IdTCPClient1.ReadTimeout := 5000; // 超时5秒 IdTCPClient1.Connect; Log('成功连接服务端'); except on E: Exception do Log('连接失败:' + E.Message); end; end; // 发送数据 procedure TForm1.btnSendClick(Sender: TObject); var SendStr, RecvStr: string; begin if not IdTCPClient1.Connected then begin Log('未连接服务端'); Exit; end; if Trim(edtSend.Text) = '' then begin Log('发送内容不能为空'); Exit; end; try SendStr := edtSend.Text; // 发送数据(按行发送,与服务端ReadLn对应) IdTCPClient1.IOHandler.WriteLn(SendStr); Log('发送数据:' + SendStr); // 读取服务端回复 RecvStr := IdTCPClient1.IOHandler.ReadLn; Log('收到回复:' + RecvStr); except on E: Exception do Log('发送失败:' + E.Message); end; end; // 断开连接 procedure TForm1.btnDisconnectClick(Sender: TObject); begin if IdTCPClient1.Connected then begin IdTCPClient1.Disconnect; Log('已断开服务端连接'); end; end; end. tm0.cn/gokdl tm0.cn/gtzo7 tm0.cn/ng6bi tm0.cn/wm7oe tm0.cn/hmax3 tm0.cn/uxune

五、运行测试步骤

  1. 先编译运行tm0.cn/hmax3服务端程序,点击【启动服务】,日志显示服务已启动,监听端口:8888
  2. 再编译运行tm0.cn/uxune客户端程序,点击【连接服务端】,日志显示成功连接服务端
  3. 客户端输入内容(如Hello Delphi TCP),点击【发送数据】;
  4. 服务端会收到客户端数据并回复,客户端同时显示服务端的回复信息;
  5. 测试多客户端:打开多个客户端程序,同时连接服务端,服务端可正常处理所有客户端通信。

六、关键注意事项

  1. 端口占用:确保 8888 端口未被其他程序占用,可在 cmd 中用netstat -ano查看;
  2. 防火墙:内网通信时,关闭服务端防火墙或放行 8888 端口;
  3. 阻塞问题:客户端数据收发会阻塞主线程,正式项目需将通信逻辑放入子线程,避免界面卡死;
  4. 数据编码:传输中文时,需指定编码(如IdTCPClient1.IOHandler.DefStringEncoding := TEncoding.UTF8),避免乱码;
  5. 异常处理:网络通信必须捕获异常(断开、超时、网络错误),保证程序稳定性。

七、扩展与进阶

  • UDP 通信:Indy 提供 TIdUDPClient/TIdUDPServer,用法与 TCP 类似,适用于实时性高、不要求可靠性的场景;
  • 数据分包:大数据传输时,需自定义协议分包发送(如添加数据长度、校验位);
  • SSL 加密:Indy 支持 TIdSSLIOHandlerSocketOpenSSL 实现加密通信,适用于敏感数据传输;
  • HTTP 通信:TIdHTTP 组件快速实现 GET/POST 请求,对接 Web API。

总结

TIdTCPClient 和 TIdTCPServer 是 Delphi 网络编程的基石,依托 Indy 组件库的封装,无需深入底层套接字编程,即可快速实现稳定的 TCP 通信。本文的实战代码可直接用于项目开发,核心掌握连接、收发数据、事件处理、异常捕获四大要点tm0.cn/dltba就能应对绝大多数 Delphi 网络开发需求。

对于新手而言,先吃透 TCP 基础通信,再逐步扩展 UDP、HTTP、SSL 等高级功能,是学习 Delphi 网络编程的最佳路径。

http://www.jsqmd.com/news/564891/

相关文章:

  • 保姆级教程:用Docker快速搭建双EMQX集群,实现跨集群数据同步
  • PicList Docker部署完全手册:快速搭建私有图床服务
  • 如何快速实现网课自动化学习:新手必看完整指南
  • 从存储优化、系统安全与更新管理维度解决Windows系统问题
  • PostgreSQL JSONB实战指南:从基础操作到高级索引优化
  • 实战演练:基于快马平台构建virtualbox多机集群,模拟企业级微服务架构
  • 2026年矿用电缆挂钩厂家推荐:保定锦宏矿山机械配件有限公司,塑钢/LJU/LJO/LJH型全系供应 - 品牌推荐官
  • Qwen3-VL-2B视觉理解机器人:5分钟快速部署,零基础搭建图文对话AI
  • QT表格编辑实战:如何让QTableWidget部分单元格可编辑(附完整代码)
  • H3C F1000防火墙忘记密码别慌,这招不丢配置进系统(实测F1000-AK115/F1020)
  • Vue工作流设计器集成指南:零基础配置与跨框架嵌入方案
  • 收藏!小白程序员轻松入门大模型:从ChatGPT到Claude Code,一篇读懂RAG检索双塔与单塔架构
  • STM32F411CEU6上,如何用FreeRTOS+LVGL搞定多传感器数据采集与UI刷新?一个健康监测项目的实战拆解
  • 2026年护栏厂家实力推荐:安平县博高丝网制品有限公司,河边/铁艺/锌钢/桥梁护栏全品类供应 - 品牌推荐官
  • UniVRM与VRM-Animation集成:制作专业级虚拟形象动画的完整方案
  • 4步让旧Mac焕发新生:开源工具OpenCore Legacy Patcher系统升级全攻略
  • 树莓派4B USB启动全攻略:告别SD卡,拥抱大容量存储
  • ComfyUI-FramePackWrapper:让AI视频生成变得简单高效的终极指南
  • 拆解ST电机库源码:TSK_MediumFrequencyTaskM1里状态机是如何被驱动的?
  • Qwen-Image-Edit极速修图:一句话指令,5分钟本地部署,小白也能玩转AI修图
  • 2026江浙沪玻璃隔断优质供应商推荐:定制化需求下的4大高适配品牌 - 速递信息
  • 仅限首批200名开发者获取:Java边缘Runtime性能调优密钥包(含GraalVM 22.3.1定制镜像)
  • 定积分
  • 重新定义离线绘图:draw.io桌面版的颠覆性价值与实践指南
  • 终极Django Silk安全配置指南:保护敏感数据与实现严格认证授权
  • OpenCV实战解析 —— 二维码定位与图像矫正技术
  • 手把手教你用ZEMAX为手机镜头做优化:从初始结构到评价函数设置全流程
  • Rust中的一些细枝末节
  • ChatRTX性能优化终极指南:提升推理速度的10个技巧
  • 别再死记硬背MAML原理了!用PyTorch手撸一个Omniglot小样本分类器(附完整代码)