idTCPServer主动向idTCPClient发送数据后,关闭程序无响应

chenylin 2019-06-27 10:20:22
用idTCPServer和idTCPClient做通讯时,只要从Server端主动发送过数据到Client端,就会出现问题:
1、在关闭软件时,出现无响应,程序不能关闭;
2、idTCPClient断开后就再也连接不上了
----------------------
用的是Delphi10.2.3自带的INDY 10.6,发送的代码也很简单:
----------------------
try
for i := 0 to IdTCPServer1.Contexts.LockList.Count - 1 do

begin
Context := TIdContext(IdTCPServer1.Contexts.LockList.Items[i]);
if Context.Binding.PeerIP = '192.168.10.22' then
begin
Context.Connection.IOHandler.Write('TEST OK');
break;
end;
end;
finally
IdTCPServer1.Contexts.UnlockList;
end;

...全文
261 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenylin 2020-09-26
  • 打赏
  • 举报
回复
自己搞定:要修改IdScheduler.pas单元 具体 的是这样的: procedure TIdScheduler.TerminateAllYarns; var i: Integer; LList: TIdYarnList; begin Assert(FActiveYarns<>nil); //LList := FActiveYarns.LockList; while True do begin // Must unlock each time to allow yarns that are terminating to remove themselves from the list LList := FActiveYarns.LockList; try if LList.Count = 0 then begin Break; end; for i := LList.Count - 1 downto 0 do begin TerminateYarn( {$IFDEF HAS_GENERICS_TList}LList.Items[i]{$ELSE}TIdYarn(LList.Items[i]){$ENDIF} ); LList.Delete(i); //增加这条语句 end; //sensor 2019-06-12 //FActiveYarns.LockList.Clear; finally FActiveYarns.UnlockList; end; IndySleep(500); // Wait a bit before looping to prevent thrashing end; //FActiveYarns.UnlockList; end;
戏言zare 2019-09-02
  • 打赏
  • 举报
回复
这里有我写的例子可以去看看
https://download.csdn.net/download/qq_37033647/11490858
BlueStorm 2019-06-29
  • 打赏
  • 举报
回复
Thread: TThread; 那一行最好改为Thread: TMyThread;
BlueStorm 2019-06-29
  • 打赏
  • 举报
回复

unit UnitClient;

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
  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  public
    constructor Create; overload;
    destructor Destroy; override;
  end;

  TFormClient = class(TForm)
    Edit1: TEdit;
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
  public
    { Public declarations }
  end;

var
  FormClient: TFormClient;
  Thread: TThread;
  IsThreadTerminated: Boolean;

implementation

{$R *.dfm}

procedure TFormClient.FormShow(Sender: TObject);
begin
  Thread := TMyThread.Create;
  IsThreadTerminated := False;
end;

procedure TFormClient.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if not IsThreadTerminated then
  begin
    Thread.Terminate;
    IsThreadTerminated := True;
  end;

  if Thread <> nil then
  begin
    Sleep(100);
    Action := caNone;
    PostMessage(Self.Handle, WM_CLOSE, 0, 0);
  end;
end;

constructor TMyThread.Create;
begin
  inherited;
  FreeOnTerminate := True;
end;

destructor TMyThread.Destroy;
begin
  inherited;
  Thread := nil;
end;

procedure TMyThread.Execute;
var
  Str: String;
  IdTCPClient: TIdTCPClient;
begin
  IdTCPClient := TIdTCPClient.Create(nil);
  IdTCPClient.Host := '192.168.2.200';
  IdTCPClient.Port := 10000;
  IdTCPClient.Connect;
  while not Terminated do
  begin
    IdTCPClient.IOHandler.CheckForDataOnSource(10);
    while not IdTCPClient.IOHandler.InputBufferIsEmpty do
    begin
      Str := IdTCPClient.IOHandler.ReadLn;
      Synchronize(procedure begin FormClient.Edit1.Text := Str; end);
    end;
  end;
  IdTCPClient.Free;
end;

end.

看那山瞧那水 2019-06-28
  • 打赏
  • 举报
回复
Write() 改成 WriteLn()试试
看那山瞧那水 2019-06-28
  • 打赏
  • 举报
回复
实际运用中得想办法判断线程是否结束了。。。
看那山瞧那水 2019-06-28
  • 打赏
  • 举报
回复
线程的Thread.Terminate; 不会立即结束线程,测试程序的话,可以加个延时试试: procedure TFormClient.FormDestroy(Sender: TObject); begin Thread.Terminate; Sleep(2000); end; 实际运用中得想办法判断线程是否接收了。。。
chenylin 2019-06-28
  • 打赏
  • 举报
回复
writeln也不行
BlueStorm 2019-06-28
  • 打赏
  • 举报
回复
服务器端:Write('TEST OK')改为WriteLn('TEST OK') 客户端:

unit UnitClient;

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
  TMyThread = class(TThread)
    protected
      procedure Execute; override;
  end;

  TFormClient = class(TForm)
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    Thread: TThread;
  public
    { Public declarations }
  end;

var
  FormClient: TFormClient;

implementation

{$R *.dfm}

procedure TFormClient.FormCreate(Sender: TObject);
begin
  Thread := TMyThread.Create(True);
  Thread.FreeOnTerminate := True;
  Thread.Start;
end;

procedure TFormClient.FormDestroy(Sender: TObject);
begin
  Thread.Terminate;
end;

procedure TMyThread.Execute;
var
  Str: String;
  IdTCPClient: TIdTCPClient;
begin
  IdTCPClient := TIdTCPClient.Create(nil);
  IdTCPClient.Host := '192.168.10.22';
  IdTCPClient.Port := 10000; //假定你的服务器端口是10000
  IdTCPClient.Connect;
  while not Terminated do
  begin
    IdTCPClient.IOHandler.CheckForDataOnSource(10);
    while not IdTCPClient.IOHandler.InputBufferIsEmpty do
    begin
      Str := IdTCPClient.IOHandler.ReadLn;
      Synchronize(procedure begin FormClient.Edit1.Text := Str; end);
    end;
  end;
  IdTCPClient.Free;
end;

end.

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧