gpt4 book ai didi

multithreading - Delphi:在主线程外创建和使用套接字

转载 作者:行者123 更新时间:2023-12-03 18:33:14 25 4
gpt4 key购买 nike

下面的代码旨在通过线程内的套接字读取数据。

//main method from dll
function GetSocketData(const IP, Port: PChar): PChar; export; cdecl;
var
Thread: TMyThread;
DataIsRead: TEvent;
begin
DataIsRead := TEvent.Create(nil, True, False, '');
Thread:= TMyThread.Create(DataIsRead, IP, Port);
DataIsRead.WaitFor(INFINITE);
Result := BlockAlloc(Thread.ResultData);
DataIsRead.Free;
Thread.Free;
end;

TMyThreadBase = class(TThread)
protected
FResultData: string;
public
constructor Create;

property ResultData: string read FResultData;
end;

constructor TMyThreadBase.Create;
begin
inherited Create(False); // Suspended
FResultData := '';
FreeOnTerminate := False;
end;

TMyThread = class(TMyThreadBase)
private
FMyData: TMyData;
FSocketCom: TSocketCom;
//other params
protected
procedure Connect(Sender: TObject);
procedure Execute; override;
public
constructor Create(DataIsRead: TEvent; const IP, Port: PChar);
destructor Destroy; override;
end;

constructor TMyThread.Create(const IP, Port: PChar);
begin
inherited Create;
/init params/

CoInitialize(nil);
FSocketCom := ComCreate(FPort, FIP);
FSocketCom.OnConnect := Connect;//Connect method sends the special command to the port {`ClientSckt.Socket.SendBuf(B[0], Count)`}
FSocketCom.Reopen;

FMyData := TMyData.Create(DataIsRead, FSocketCom);//class used for received data interpretation
//DataIsRead event is being set when all data is interpreted
FSocketCom.SetRxFunc(FMyData.NCData);//set method for data interpretation
FMyData.InitData(...);//init values needed while data is being interpreted
end;

destructor TMyThread.Destroy;
begin
CoUninitialize;
inherited;
end;

procedure TMyThread.Execute;
begin
inherited;
while not Terminated do
Sleep(100);
//that is the place where I do not know what to do to wait while OnRead event is fired.
end;

TSocketCom = class(TCustomCom)
private
ClientSckt: TClientSocket;

procedure SocketConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure SocketRead(Sender: TObject; Socket: TCustomWinSocket);
protected
procedure SetThread; override;
public
constructor Create;
destructor Destroy; override;
function Open:Boolean; override;
function Read( Buf:PAnsiChar; Size:Integer; Wait:Integer = 0 ):Integer; override;
end;

procedure TCustomCom.SetRxFunc(OnRxData: TRxDataEvent);
begin
...
SetThread;
...
end;

function TSocketCom.Open:boolean;
var
i,j:integer;
begin
...
ClientSckt:=TClientSocket.Create(nil);
ClientSckt.ClientType:=ctBlocking;
ClientSckt.HostAndAddress:='127.0.0.0';
ClientSckt.Port:=1234;
ClientSckt.OnConnect:=SocketConnect;
ClientSckt.Open;
...
end;

function TSocketCom.Read(Buf:PAnsiChar;Size:Integer; Wait:Integer):Integer;
begin
if Opened then
Result:=ClientSckt.Socket.ReceiveBuf(Buf^,Size);
if Result<0 then Result:=0;
end;

procedure TSocketCom.SetThread;
begin
inherited;
ClientSckt.OnRead:=SocketRead;
end;

问题: OnRead 事件没有被触发,尽管它接缝在线程中创建了所有需要的实例。建立连接并发送命令。

最佳答案

这种代码是对线程的滥用(以及对FreeOnTerminate 属性的滥用),因为调用代码被阻塞等待线程终止,所以首先没有理由拥有线程。

话虽如此,默认情况下 TClientSocket在非阻塞模式下运行,它在内部使用窗口消息来触发套接字事件。激活套接字的线程需要有一个消息循环,以便可以正确接收和发送这些套接字通知。否则,正如马丁所说,您必须在阻塞模式下使用套接字。

更新:

您显示的更新代码在多个级别上都是完全错误的。线程全错了。 TClientSocket用法都是错的。鉴于您的 GetSocketData() 的阻塞性质函数,根本不需要在内部使用任何线程(特别是因为你说 GetSocketData() 本身是在一个线程中调用的,所以额外的线程是矫枉过正的),而且你不应该为 TClientSocket 而烦恼。事件,尤其是 OnRead尤其是事件,因为它根本不会在阻塞模式下被调用(这是您问题的根源!)。

你让你的代码变得更复杂了。使用更像这样的东西:

function GetSocketData(const IP, Port: PChar): PChar; export; cdecl; 
var
ClientSckt: TClientSocket;
//other params
begin
Result := nil;
try
/init params/

CoInitialize(nil);
try
ClientSckt := TClientSocket.Create(nil);
try
ClientSckt.ClientType := ctBlocking;
ClientSckt.HostAndAddress := IP;
ClientSckt.Port := Port;
ClientSckt.Open;
try
// send the special command to the port from here
// read all data and interpret from here
Result := BlockAlloc(...);
finally
ClientSckt.Close;
end;
finally
ClientSckt.Free;
end;
finally
CoUninitialize;
end;
except
end;
end;

关于multithreading - Delphi:在主线程外创建和使用套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8834924/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com