[I've followed the suggestion to use Winsock.pas, but it still writes garbage -- although the sin_family field has changed to a new garbage value.]
Hello, I'm trying to write a quick/dirty echoserver in Delphi, but I notice that GetAcceptExSockaddrs seems to be writing to only the first 4 bytes of the structure I pass it.
program TCPEcho;
{$APPTYPE CONSOLE}
uses Windows, SysUtils, Winsock;
type INT = SmallInt;
const
BufDataSize = 8192;
BufAddrSize = SizeOf (TSockAddrIn) + 16;
var
WSAData : TWSAData;
ListenSock, AcceptSock : TSocket;
Addr, LocalAddr, RemoteAddr : TSockAddrIn;
LocalAddrSize, RemoteAddrSize : Integer;
Ov : OVERLAPPED;
Buf : array[1..BufDataSize + BufAddrSize * 2] of Byte;
BytesReceived : DWORD;
begin
FillChar (WSAData, SizeOf (WSAData), 0);
WSAStartup (2, WSAData);
ListenSock := ValidSocketCheck ('Socket', Socket (AF_INET, SOCK_STREAM, IPPROTO_TCP));
FillChar (Addr, SizeOf (Addr), 0);
Addr.sin_family := AF_INET;
Addr.sin_port := HToNS (1066);
Addr.sin_addr.s_addr := HToNL (INADDR_ANY);
SocketCheck ('bind', bind (ListenSock, Addr, SizeOf (Addr)));
SocketCheck ('Listen', Listen (ListenSock, 3));
FillChar (Ov, SizeOf (Ov), 0);
Ov.hEvent := HandleCheck ('CreateEvent', CreateEvent (nil, False, False, nil));
AcceptSock := ValidSocketCheck ('Socket', Socket (AF_INET, SOCK_STREAM, IPPROTO_TCP));
if AcceptEx (ListenSock, AcceptSock, @Buf, BufDataSize, BufAddrSize, BufAddrSize, BytesReceived, @Ov) then
WinCheck ('SetEvent', SetEvent (Ov.hEvent))
else
if GetLastError <> ERROR_IO_PENDING then
WinCheck ('AcceptEx', GetLastError);
if WaitForMultipleObjects (1, @Ov.hEvent, False, INFINITE) <> WAIT_OBJECT_0 then
raise Exception.Create ('WFMO');
GetAcceptExSockaddrs (@Buf, BufDataSize, BufAddrSize, BufAddrSize, LocalAddr, LocalAddrSize, RemoteAddr, RemoteAddrSize);
WriteLn (RemoteAddr.sin_family);
end.
So if I run this, connect to it with Telnet (on same computer, connecting to localhost) and then type a key, WaitForMultipleObjects will unblock and GetAcceptExSockaddrs will run. But the result is garbage!
RemoteAddr.sin_family = 51618
RemoteAddr.sin_port = 64
and the rest is zeroes.
What gives? Thanks in advance!