2010-05-22 50 views
0

[我按照建議使用Winsock.pas,但它仍然寫垃圾 - 雖然sin_family字段已更改爲新的垃圾值。]GetAcceptExSockaddrs返回垃圾!有誰知道爲什麼?

您好,我正在嘗試寫一個快速/德爾福的髒回聲,但我 注意到,GetAcceptExSockaddrs似乎只寫入我通過它的結構的第一個4 字節。

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. 

所以,如果我運行此,通過telnet連接到它(同一臺計算機上, 連接到本地主機),然後鍵入一個鍵,WaitForMultipleObjects的 將疏通和GetAcceptExSockAddrs的運行。 但結果是垃圾!

RemoteAddr.sin_family = 51618 
RemoteAddr.sin_port = 64 

其餘的爲零。

什麼給? 在此先感謝!

回答

1

你使用的是什麼Delphi版本?在任何情況下,無需爲GetAcceptExSockaddrs及其參數使用自己的類型定義,請使用WinSock.pas單元中的定義;至少對於unicode的Delphi版本,它們與你的定義有所不同。


更新

貌似GetAcceptExSockAddrs的定義是錯誤的。我記得舊的Delphi版本在這裏包含一個bug。正確的原型(2009年德爾福WinSock.pas拍攝)是

procedure GetAcceptExSockaddrs(lpOutputBuffer: Pointer; 
    dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: DWORD; 
    var LocalSockaddr: PSockAddr; var LocalSockaddrLength: Integer; 
    var RemoteSockaddr: PSockAddr; var RemoteSockaddrLength: Integer); stdcall; 

注意LocalSockaddr和RemoteSockaddr不是指向結構的指針,但指針指向結構的指針。

+0

德爾福7 。 sin_family字段是一個不同的垃圾值,但否則問題依然存在。 – David 2010-05-22 09:18:56

+0

Thankyou,這工作。 – David 2010-05-22 12:07:03

0

如果使用mingw的GetAcceptExSockaddrs原型,則會發生同樣的情況。它返回垃圾。

,即可解決GetAcceptExSockAddrs的我已經調整問題描述代碼使用Winsock.pas的定義你解決的AcceptEx和ConnectEx以同樣的方式,即:

#define WSAID_GETACCEPTEXSOCKADDRS { 0xb5367df2,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92} } 

GUID GuidGetAcceptSockAddrs = WSAID_GETACCEPTEXSOCKADDRS; 
DWORD dwBytes; 

if (WSAIoctl(activeSock, 
       SIO_GET_EXTENSION_FUNCTION_POINTER, 
       &GuidGetAcceptSockAddrs, 
       sizeof (GuidGetAcceptSockAddrs), 
       &pfnGetAcceptSockAddrs, 
       sizeof (pfnGetAcceptSockAddrs), 
       &dwBytes, 
       NULL, 
       NULL) == SOCKET_ERROR) 
{ 
    ... error ... 
}