关于Delphi 10.4.2 TIdTCPServer 的多线程通信使用

本文介绍了在Delphi 10.4.2中使用TIdTCPServer和TIdTCPClient进行多线程通信的实现方法,特别关注了TIdTCPServer的线程调度和处理。通过自定义TIdServerContext类来保存用户数据,并详细说明了OnConnect、OnDisconnect和OnExecute事件的处理,以及如何在处理VCL控件时确保线程安全。在停止服务器监听时,提出了处理多个客户端连接时避免线程锁死的策略,即先断开所有客户端连接,再用定时器确保所有线程结束后再停止监听服务。
摘要由CSDN通过智能技术生成

前几年在博客看到有人写过类似的例子,但是都忘记了,无奈最近由于项目需要用到
所以又重新研究了一下TIdTCPServer和TIdTCPClient控件
以前有写过Indy 10发送数据的例子,
不懂的朋友可以在这里下载:
https://download.csdn.net/download/zhou752947/10213169
使用的是Delphi 10.2.2,但是最近我用Delphi10.4.2编译后发现传输文件有问题,其他都正常,有时间的朋友自己研究去吧

进入正题:
IDE工具:Delphi 10.4.2
Indy版本:10.6.5

至于多线程,官方文档就有说明,其实TIdTCPServer运行过程中,当客户端连接成功后默认就是基于TIdSchedulerOfThreadDefault调度分配线程模式,为每个客户端连接都分配单独的处理线程,由于Windows线程的限制,Indy 似乎还有一种特殊的模式TIdYarnOfThread来代替传统线程,至于TIdYarnOfThread这里不做研究,开始上代码

1.启动按钮事件

IdTCPServer1.DefaultPort:= 8000;
IdTCPServer1.ListenQueue:= 1024; //同时处理请求队列数限制
IdTCPServer1.MaxConnections:= 1024;  //同时连接数量限制,为0不限制连接数
IdTCPServer1.ContextClass:= TNewIdServerContext; //设置为自定义TIdServerContext类,作用稍后说明
TIdServerContext.Active:= True;	//启动监听

2.自定义TIdServerContext类
定义这个类的好处就是用于保存用户的个人数据等等

unit uNewIdServerContext;

interface

uses Winapi.Windows, IdCustomTCPServer, IdTCPConnection, IdYarn, IdContext;

type
  TNewIdServerContext = class(TIdServerContext)
    public
      constructor Create(AConnection: TIdTCPConnection
本例子就是Delphi中如何利用Socket编写通信程序。 计算机网络是由一系列网络通信协议组成的,其中的核心协议是传输层的TCP/IP和UDP协议。TCP是面向连接的,通信双方保持一条通路,好比目前的电话线,使用telnet登陆BBS,用的就是TCP协议;UDP是无连接的,通信双方都不保持对方的状态,浏览器访问Internet时使用的HTTP协议就是基于UDP协议的。TCP和UDP协议都非常复杂,尤其是TCP协议,为了保证网络传输的正确性和有效性,必须进行一系列复杂的纠错和排序等处理。   Socket是建立在传输层协议(主要是TCP和UDP)上的一种套接字规范,最初是由美国加州Berkley大学提出,它定义两台计算机间进行通信的规范(也是一种编程规范),如果说两台计算机是利用一个“通道“进行通信,那么这个“通道“的两端就是两个套接字。套接字屏蔽了底层通信软件和具体操作系统的差异,使得任何两台安装了TCP协议软件和实现了套接字规范的计算机之间的通信成为可能。   微软的Windows Socket规范(简称winsock)对Berkley的套接字规范进行了扩展,利用标准的Socket的方法,可以同任何平台上的Socket进行通信;利用其扩展,可以更有效地实现在Windows平台上计算机间的通信。在Delphi中,其底层的Socket也应该是Windows的Socket。Socket减轻了编写计算机间通信软件的难度,但总的说来还是相当复杂的(这一点在后面具体会讲到);Inprise在Delphi中对Windows Socket进行了有效的封装,使得用户可以很方便地编写网络通信程序。 本例子就是Delphi中如何利用Socket编写通信程序。
下面是一个简单的 Delphi 10.4.2 安卓线程实例代码: ```delphi unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls; type TMyThread = class(TThread) private FLabel: TLabel; FValue: Integer; public constructor Create(ALabel: TLabel; AValue: Integer); procedure Execute; override; property Value: Integer read FValue; end; TForm1 = class(TForm) Button1: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); private FThread: TMyThread; public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} constructor TMyThread.Create(ALabel: TLabel; AValue: Integer); begin inherited Create(True); FLabel := ALabel; FValue := AValue; end; procedure TMyThread.Execute; var I: Integer; begin for I := 1 to FValue do begin Sleep(1000); // 模拟一些耗时的操作 Synchronize( procedure begin FLabel.Text := Format('已完成 %d 秒', [I]); end ); end; end; procedure TForm1.Button1Click(Sender: TObject); begin FThread := TMyThread.Create(Label1, 10); FThread.Start; end; end. ``` 这段代码中,我们定义了一个 `TMyThread` 类,它继承自 `TThread`。在 `TMyThread` 类中,我们定义了一个 `Value` 属性,用于存储要执行的操作次数。在 `Execute` 方法中,我们使用 `for` 循环模拟一些耗时的操作,并通过 `Synchronize` 方法更新 UI 界面。在主界面中,当用户点击 `Button1` 按钮时,我们创建了一个 `TMyThread` 对象,并调用 `Start` 方法启动线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值