用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;
uj5u.com熱心網友回復:
Write() 改成 WriteLn()試試uj5u.com熱心網友回復:
服務器端: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.
uj5u.com熱心網友回復:
writeln也不行uj5u.com熱心網友回復:
執行緒的Thread.Terminate; 不會立即結束執行緒,測驗程式的話,可以加個延時試試:procedure TFormClient.FormDestroy(Sender: TObject);
begin
Thread.Terminate;
Sleep(2000);
end;
實際運用中得想辦法判斷執行緒是否接收了。。。
uj5u.com熱心網友回復:
實際運用中得想辦法判斷執行緒是否結束了。。。uj5u.com熱心網友回復:
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.
uj5u.com熱心網友回復:
Thread: TThread; 那一行最好改為Thread: TMyThread;uj5u.com熱心網友回復:
這里有我寫的例子可以去看看https://download.csdn.net/download/qq_37033647/11490858
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/24167.html
標籤:網絡通信/分布式開發
