在 Delphi 开发中网络通信是桌面应用、服务端程序、物联网设备交互的核心需求。IndyInternet Direct组件库是 Delphi 内置的老牌网络开发工具包基于阻塞式套接字实现封装了 TCP、UDP、HTTP 等主流网络协议其中TIdTCPClientTCP 客户端和TIdTCPServerTCP 服务端是实现自定义 TCP 通信的核心类也是 Delphi 网络编程的基础。本文将从零讲解这两个核心类的用法、关键属性 / 方法、线程安全机制并提供完整的客户端 服务端通信实战代码。一、Indy 组件库基础Indy 是 Delphi 自带的跨平台网络组件库无需额外安装直接在组件面板的Indy Clients和Indy Servers分类中调用TIdTCPClient客户端组件用于主动连接服务端、发送 / 接收数据TIdTCPServer服务端组件用于监听端口、接受客户端连接、处理多客户端通信核心特性阻塞式通信数据收发时会阻塞当前线程需配合线程避免界面卡死、支持多客户端连接、内置数据编码 / 解码、异常捕获机制。适用场景自定义协议通信、设备控制、内网数据传输、服务端监听等。二、TIdTCPClient 客户端核心详解1. 关键属性表格属性名作用Host目标服务端的 IP 地址如127.0.0.1本地回环、192.168.1.100内网 IPPort目标服务端的监听端口需与服务端一致范围 1~65535Connected只读属性判断是否与服务端建立连接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 监听所有网卡可指定内网 IPContexts存储所有已连接的客户端上下文用于遍历在线客户端2. 核心事件服务端核心逻辑OnConnect客户端成功连接时触发可记录客户端信息OnDisconnect客户端断开连接时触发清理资源OnExecute核心事件客户端发送数据时触发用于接收 / 处理数据、回复客户端OnException捕获通信过程中的异常避免服务端崩溃。3. 线程安全机制TIdTCPServer 内置多线程管理每一个客户端连接都会分配一个独立线程TIdContext所有客户端通信互不干扰无需手动创建线程这是 Indy 最实用的特性。四、实战Delphi TCP 客户端 服务端完整实现环境准备Delphi 7/XE/10.X 版本本文以 Delphi 10.4 为例新建两个 VCL 工程TCPClientDemo客户端、TCPServerDemo服务端。第一部分服务端开发TCPServerDemo1. 界面设计1 个TMemo名称memoLog显示日志2 个TButtonbtnStart 启动服务btnStop 停止服务1 个TIdTCPServer名称IdTCPServer1拖入界面即可。2. 完整代码delphiunit 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.第二部分客户端开发TCPClientDemo1. 界面设计1 个TMemomemoLog显示通信日志1 个TEditedtSend输入发送内容3 个TButtonbtnConnect 连接服务端btnSend 发送数据btnDisconnect 断开连接1 个TIdTCPClientIdTCPClient1拖入界面。2. 完整代码delphiunit 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五、运行测试步骤先编译运行tm0.cn/hmax3服务端程序点击【启动服务】日志显示服务已启动监听端口8888再编译运行tm0.cn/uxune客户端程序点击【连接服务端】日志显示成功连接服务端客户端输入内容如Hello Delphi TCP点击【发送数据】服务端会收到客户端数据并回复客户端同时显示服务端的回复信息测试多客户端打开多个客户端程序同时连接服务端服务端可正常处理所有客户端通信。六、关键注意事项端口占用确保 8888 端口未被其他程序占用可在 cmd 中用netstat -ano查看防火墙内网通信时关闭服务端防火墙或放行 8888 端口阻塞问题客户端数据收发会阻塞主线程正式项目需将通信逻辑放入子线程避免界面卡死数据编码传输中文时需指定编码如IdTCPClient1.IOHandler.DefStringEncoding : TEncoding.UTF8避免乱码异常处理网络通信必须捕获异常断开、超时、网络错误保证程序稳定性。七、扩展与进阶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 网络编程的最佳路径。
Delphi 网络编程实战:TIdTCPClient 与 TIdTCPServer 类深度解析
发布时间:2026/5/28 13:12:58
在 Delphi 开发中网络通信是桌面应用、服务端程序、物联网设备交互的核心需求。IndyInternet Direct组件库是 Delphi 内置的老牌网络开发工具包基于阻塞式套接字实现封装了 TCP、UDP、HTTP 等主流网络协议其中TIdTCPClientTCP 客户端和TIdTCPServerTCP 服务端是实现自定义 TCP 通信的核心类也是 Delphi 网络编程的基础。本文将从零讲解这两个核心类的用法、关键属性 / 方法、线程安全机制并提供完整的客户端 服务端通信实战代码。一、Indy 组件库基础Indy 是 Delphi 自带的跨平台网络组件库无需额外安装直接在组件面板的Indy Clients和Indy Servers分类中调用TIdTCPClient客户端组件用于主动连接服务端、发送 / 接收数据TIdTCPServer服务端组件用于监听端口、接受客户端连接、处理多客户端通信核心特性阻塞式通信数据收发时会阻塞当前线程需配合线程避免界面卡死、支持多客户端连接、内置数据编码 / 解码、异常捕获机制。适用场景自定义协议通信、设备控制、内网数据传输、服务端监听等。二、TIdTCPClient 客户端核心详解1. 关键属性表格属性名作用Host目标服务端的 IP 地址如127.0.0.1本地回环、192.168.1.100内网 IPPort目标服务端的监听端口需与服务端一致范围 1~65535Connected只读属性判断是否与服务端建立连接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 监听所有网卡可指定内网 IPContexts存储所有已连接的客户端上下文用于遍历在线客户端2. 核心事件服务端核心逻辑OnConnect客户端成功连接时触发可记录客户端信息OnDisconnect客户端断开连接时触发清理资源OnExecute核心事件客户端发送数据时触发用于接收 / 处理数据、回复客户端OnException捕获通信过程中的异常避免服务端崩溃。3. 线程安全机制TIdTCPServer 内置多线程管理每一个客户端连接都会分配一个独立线程TIdContext所有客户端通信互不干扰无需手动创建线程这是 Indy 最实用的特性。四、实战Delphi TCP 客户端 服务端完整实现环境准备Delphi 7/XE/10.X 版本本文以 Delphi 10.4 为例新建两个 VCL 工程TCPClientDemo客户端、TCPServerDemo服务端。第一部分服务端开发TCPServerDemo1. 界面设计1 个TMemo名称memoLog显示日志2 个TButtonbtnStart 启动服务btnStop 停止服务1 个TIdTCPServer名称IdTCPServer1拖入界面即可。2. 完整代码delphiunit 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.第二部分客户端开发TCPClientDemo1. 界面设计1 个TMemomemoLog显示通信日志1 个TEditedtSend输入发送内容3 个TButtonbtnConnect 连接服务端btnSend 发送数据btnDisconnect 断开连接1 个TIdTCPClientIdTCPClient1拖入界面。2. 完整代码delphiunit 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五、运行测试步骤先编译运行tm0.cn/hmax3服务端程序点击【启动服务】日志显示服务已启动监听端口8888再编译运行tm0.cn/uxune客户端程序点击【连接服务端】日志显示成功连接服务端客户端输入内容如Hello Delphi TCP点击【发送数据】服务端会收到客户端数据并回复客户端同时显示服务端的回复信息测试多客户端打开多个客户端程序同时连接服务端服务端可正常处理所有客户端通信。六、关键注意事项端口占用确保 8888 端口未被其他程序占用可在 cmd 中用netstat -ano查看防火墙内网通信时关闭服务端防火墙或放行 8888 端口阻塞问题客户端数据收发会阻塞主线程正式项目需将通信逻辑放入子线程避免界面卡死数据编码传输中文时需指定编码如IdTCPClient1.IOHandler.DefStringEncoding : TEncoding.UTF8避免乱码异常处理网络通信必须捕获异常断开、超时、网络错误保证程序稳定性。七、扩展与进阶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 网络编程的最佳路径。