我正在尝试创建一个支持超时参数的connect
包装器。
主要功能应如下所示:
function ConnectToHost (Host : PAnsiChar; Port : Word; Timeout: DWORD): Integer;
我也希望尽可能简单,并将套接字保持在阻塞模式。
此外,我们的想法是使用纯Winsock API而不使用Indy组件或任何东西。
主函数应返回一个Integer,以获取有关所发生事件的其他信息。
我在想的是connect
函数返回的返回值以及超时信息的其他值。
在main函数内部有一个线程负责连接,而main函数在给定的超时时间内等待线程。
现在我担心将主机和端口等数据传递给线程和内存泄漏。
我正在考虑将这些API用于超时操作:
CreateThread
WaitForSingleObject
GetExitCodeThread
TerminateThread
?和使用winsock的TCP连接的这些API:
socket
htons
inet_addr
connect
如果考虑超时限制,安全connect
包装器怎么样呢?
现在我似乎不知道如何才能做到这一点。任何帮助,将不胜感激。
答案 0 :(得分:3)
尝试这样的事情:
type
PConnectInfo = ^ConnectInfo;
ConnectInfo = record
Socket: TSocket;
Addr: sockaddr_in;
ErrCode: Integer;
end;
function ConnectProc(Param : Pointer): DWORD; stdcall;
begin
With PConnectInfo(Param)^ do
begin
if connect(Socket, PAddrInfo(@Addr), SizeOf(Addr)) = 0 then
ErrCode := 0
else
ErrCode := WSAGetLastError;
end;
Result := 0;
end;
function ConnectToHost (Host : PAnsiChar; Port : Word; Timeout: DWORD): Integer;
var
ci: ConnectInfo;
H: THandle;
tid: DWORD;
begin
Result := 0;
ZeroMemory(@ci, SizeOf(ci));
ci.Socket := ...;
ZeroMemory(@ci, SizeOf(ci));
ci.Addr.sin_family := AF_INET;
ci.Addr.sin_addr.s_addr := inet_addr(Host);
ci.Addr.sin_port := htons(Port);
if Timeout = INFINITE then
begin
ConnectProc(@ci);
end else
begin
h := CreateThread(nil, 0, @ConnectProc, @ci, 0, @tid);
if h = 0 then
begin
Result := GetLastError;
Exit;
end;
case WaitForSingleObject(h, Timeout) of
WAIT_FAILED: begin
Result := GetLastError;
end;
WAIT_OBJECT_0: begin
Result := ci.ErrCode;
end;
WAIT_TIMEOUT: begin
Result := WSAETIMEDOUT;
end;
else
Result := -1;
end;
CloseHandle(h);
end;
if Result <> 0 then
closesocket(ci.Socket);
end;