📄 sswin32.pas
字号:
stdcall;
TCloseSocket = function(s: TSocket): Integer;
stdcall;
TBind = function(s: TSocket; addr: PSockAddr; namelen: Integer): Integer;
stdcall;
TAccept = function(s: TSocket; addr: PSockAddr; var addrlen: Integer): TSocket;
stdcall;
TTSocket = function(af, Struc, Protocol: Integer): TSocket;
stdcall;
TSelect = function(nfds: Integer; readfds, writefds, exceptfds: PFDSet;
timeout: PTimeVal): Longint;
stdcall;
TGetAddrInfo = function(NodeName: PChar; ServName: PChar; Hints: PAddrInfo;
var Addrinfo: PAddrInfo): integer;
stdcall;
TFreeAddrInfo = procedure(ai: PAddrInfo);
stdcall;
TGetNameInfo = function( addr: PSockAddr; namelen: Integer; host: PChar;
hostlen: DWORD; serv: PChar; servlen: DWORD; flags: integer): integer;
stdcall;
T__WSAFDIsSet = function (s: TSocket; var FDSet: TFDSet): Bool;
stdcall;
TWSAIoctl = function (s: TSocket; dwIoControlCode: DWORD; lpvInBuffer: Pointer;
cbInBuffer: DWORD; lpvOutBuffer: Pointer; cbOutBuffer: DWORD;
lpcbBytesReturned: PDWORD; lpOverlapped: Pointer;
lpCompletionRoutine: pointer): u_int;
stdcall;
var
WSAStartup: TWSAStartup = nil;
WSACleanup: TWSACleanup = nil;
WSAGetLastError: TWSAGetLastError = nil;
GetServByName: TGetServByName = nil;
GetServByPort: TGetServByPort = nil;
GetProtoByName: TGetProtoByName = nil;
GetProtoByNumber: TGetProtoByNumber = nil;
GetHostByName: TGetHostByName = nil;
GetHostByAddr: TGetHostByAddr = nil;
ssGetHostName: TGetHostName = nil;
Shutdown: TShutdown = nil;
SetSockOpt: TSetSockOpt = nil;
GetSockOpt: TGetSockOpt = nil;
ssSendTo: TSendTo = nil;
ssSend: TSend = nil;
ssRecv: TRecv = nil;
ssRecvFrom: TRecvFrom = nil;
ntohs: Tntohs = nil;
ntohl: Tntohl = nil;
Listen: TListen = nil;
IoctlSocket: TIoctlSocket = nil;
Inet_ntoa: TInet_ntoa = nil;
Inet_addr: TInet_addr = nil;
htons: Thtons = nil;
htonl: Thtonl = nil;
ssGetSockName: TGetSockName = nil;
ssGetPeerName: TGetPeerName = nil;
ssConnect: TConnect = nil;
CloseSocket: TCloseSocket = nil;
ssBind: TBind = nil;
ssAccept: TAccept = nil;
Socket: TTSocket = nil;
Select: TSelect = nil;
GetAddrInfo: TGetAddrInfo = nil;
FreeAddrInfo: TFreeAddrInfo = nil;
GetNameInfo: TGetNameInfo = nil;
__WSAFDIsSet: T__WSAFDIsSet = nil;
WSAIoctl: TWSAIoctl = nil;
var
SynSockCS: SyncObjs.TCriticalSection;
SockEnhancedApi: Boolean;
SockWship6Api: Boolean;
type
TVarSin = packed record
case integer of
0: (AddressFamily: u_short);
1: (
case sin_family: u_short of
AF_INET: (sin_port: u_short;
sin_addr: TInAddr;
sin_zero: array[0..7] of Char);
AF_INET6: (sin6_port: u_short;
sin6_flowinfo: u_long;
sin6_addr: TInAddr6;
sin6_scope_id: u_long);
);
end;
function SizeOfVarSin(sin: TVarSin): integer;
function Bind(s: TSocket; const addr: TVarSin): Integer;
function Connect(s: TSocket; const name: TVarSin): Integer;
function GetSockName(s: TSocket; var name: TVarSin): Integer;
function GetPeerName(s: TSocket; var name: TVarSin): Integer;
function GetHostName: string;
function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
function Accept(s: TSocket; var addr: TVarSin): TSocket;
{==============================================================================}
implementation
var
SynSockCount: Integer = 0;
LibHandle: THandle = 0;
Libwship6Handle: THandle = 0;
function IN6_IS_ADDR_UNSPECIFIED(const a: PInAddr6): boolean;
begin
Result := ((a^.s_un_dw.s_dw1 = 0) and (a^.s_un_dw.s_dw2 = 0) and
(a^.s_un_dw.s_dw3 = 0) and (a^.s_un_dw.s_dw4 = 0));
end;
function IN6_IS_ADDR_LOOPBACK(const a: PInAddr6): boolean;
begin
Result := ((a^.s_un_dw.s_dw1 = 0) and (a^.s_un_dw.s_dw2 = 0) and
(a^.s_un_dw.s_dw3 = 0) and
(a^.s_un_b.s_b13 = char(0)) and (a^.s_un_b.s_b14 = char(0)) and
(a^.s_un_b.s_b15 = char(0)) and (a^.s_un_b.s_b16 = char(1)));
end;
function IN6_IS_ADDR_LINKLOCAL(const a: PInAddr6): boolean;
begin
Result := ((a^.s_un_b.s_b1 = u_char($FE)) and (a^.s_un_b.s_b2 = u_char($80)));
end;
function IN6_IS_ADDR_SITELOCAL(const a: PInAddr6): boolean;
begin
Result := ((a^.s_un_b.s_b1 = u_char($FE)) and (a^.s_un_b.s_b2 = u_char($C0)));
end;
function IN6_IS_ADDR_MULTICAST(const a: PInAddr6): boolean;
begin
Result := (a^.s_un_b.s_b1 = char($FF));
end;
function IN6_ADDR_EQUAL(const a: PInAddr6; const b: PInAddr6): boolean;
begin
Result := (CompareMem( a, b, sizeof(TInAddr6)));
end;
procedure SET_IN6_IF_ADDR_ANY (const a: PInAddr6);
begin
FillChar(a^, sizeof(TInAddr6), 0);
end;
procedure SET_LOOPBACK_ADDR6 (const a: PInAddr6);
begin
FillChar(a^, sizeof(TInAddr6), 0);
a^.s_un_b.s_b16 := char(1);
end;
{=============================================================================}
procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);
var
I: Integer;
begin
I := 0;
while I < FDSet.fd_count do
begin
if FDSet.fd_array[I] = Socket then
begin
while I < FDSet.fd_count - 1 do
begin
FDSet.fd_array[I] := FDSet.fd_array[I + 1];
Inc(I);
end;
Dec(FDSet.fd_count);
Break;
end;
Inc(I);
end;
end;
function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;
begin
Result := __WSAFDIsSet(Socket, FDSet);
end;
procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);
begin
if FDSet.fd_count < FD_SETSIZE then
begin
FDSet.fd_array[FDSet.fd_count] := Socket;
Inc(FDSet.fd_count);
end;
end;
procedure FD_ZERO(var FDSet: TFDSet);
begin
FDSet.fd_count := 0;
end;
{=============================================================================}
function SizeOfVarSin(sin: TVarSin): integer;
begin
case sin.sin_family of
AF_INET:
Result := SizeOf(TSockAddrIn);
AF_INET6:
Result := SizeOf(TSockAddrIn6);
else
Result := 0;
end;
end;
{=============================================================================}
function Bind(s: TSocket; const addr: TVarSin): Integer;
begin
Result := ssBind(s, @addr, SizeOfVarSin(addr));
end;
function Connect(s: TSocket; const name: TVarSin): Integer;
begin
Result := ssConnect(s, @name, SizeOfVarSin(name));
end;
function GetSockName(s: TSocket; var name: TVarSin): Integer;
var
len: integer;
begin
len := SizeOf(name);
FillChar(name, len, 0);
Result := ssGetSockName(s, @name, Len);
end;
function GetPeerName(s: TSocket; var name: TVarSin): Integer;
var
len: integer;
begin
len := SizeOf(name);
FillChar(name, len, 0);
Result := ssGetPeerName(s, @name, Len);
end;
function GetHostName: string;
var
s: string;
begin
Result := '';
setlength(s, 255);
ssGetHostName(pchar(s), Length(s) - 1);
Result := Pchar(s);
end;
function Send(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
begin
Result := ssSend(s, Buf^, len, flags);
end;
function Recv(s: TSocket; Buf: TMemory; len, flags: Integer): Integer;
begin
Result := ssRecv(s, Buf^, len, flags);
end;
function SendTo(s: TSocket; Buf: TMemory; len, flags: Integer; addrto: TVarSin): Integer;
begin
Result := ssSendTo(s, Buf^, len, flags, @addrto, SizeOfVarSin(addrto));
end;
function RecvFrom(s: TSocket; Buf: TMemory; len, flags: Integer; var from: TVarSin): Integer;
var
x: integer;
begin
x := SizeOf(from);
Result := ssRecvFrom(s, Buf^, len, flags, @from, x);
end;
function Accept(s: TSocket; var addr: TVarSin): TSocket;
var
x: integer;
begin
x := SizeOf(addr);
Result := ssAccept(s, @addr, x);
end;
{=============================================================================}
function InitSocketInterface(stack: string): Boolean;
begin
Result := False;
SockEnhancedApi := False;
if stack = '' then
stack := DLLStackName;
SynSockCS.Enter;
try
if SynSockCount = 0 then
begin
SockEnhancedApi := False;
SockWship6Api := False;
LibHandle := LoadLibrary(PChar(Stack));
if LibHandle <> 0 then
begin
WSAIoctl := GetProcAddress(LibHandle, PChar('WSAIoctl'));
__WSAFDIsSet := GetProcAddress(LibHandle, PChar('__WSAFDIsSet'));
CloseSocket := GetProcAddress(LibHandle, PChar('closesocket'));
IoctlSocket := GetProcAddress(LibHandle, PChar('ioctlsocket'));
WSAGetLastError := GetProcAddress(LibHandle, PChar('WSAGetLastError'));
WSAStartup := GetProcAddress(LibHandle, PChar('WSAStartup'));
WSACleanup := GetProcAddress(LibHandle, PChar('WSACleanup'));
ssAccept := GetProcAddress(LibHandle, PChar('accept'));
ssBind := GetProcAddress(LibHandle, PChar('bind'));
ssConnect := GetProcAddress(LibHandle, PChar('connect'));
ssGetPeerName := GetProcAddress(LibHandle, PChar('getpeername'));
ssGetSockName := GetProcAddress(LibHandle, PChar('getsockname'));
GetSockOpt := GetProcAddress(LibHandle, PChar('getsockopt'));
Htonl := GetProcAddress(LibHandle, PChar('htonl'));
Htons := GetProcAddress(LibHandle, PChar('htons'));
Inet_Addr := GetProcAddress(LibHandle, PChar('inet_addr'));
Inet_Ntoa := GetProcAddress(LibHandle, PChar('inet_ntoa'));
Listen := GetProcAddress(LibHandle, PChar('listen'));
Ntohl := GetProcAddress(LibHandle, PChar('ntohl'));
Ntohs := GetProcAddress(LibHandle, PChar('ntohs'));
ssRecv := GetProcAddress(LibHandle, PChar('recv'));
ssRecvFrom := GetProcAddress(LibHandle, PChar('recvfrom'));
Select := GetProcAddress(LibHandle, PChar('select'));
ssSend := GetProcAddress(LibHandle, PChar('send'));
ssSendTo := GetProcAddress(LibHandle, PChar('sendto'));
SetSockOpt := GetProcAddress(LibHandle, PChar('setsockopt'));
ShutDown := GetProcAddress(LibHandle, PChar('shutdown'));
Socket := GetProcAddress(LibHandle, PChar('socket'));
GetHostByAddr := GetProcAddress(LibHandle, PChar('gethostbyaddr'));
GetHostByName := GetProcAddress(LibHandle, PChar('gethostbyname'));
GetProtoByName := GetProcAddress(LibHandle, PChar('getprotobyname'));
GetProtoByNumber := GetProcAddress(LibHandle, PChar('getprotobynumber'));
GetServByName := GetProcAddress(LibHandle, PChar('getservbyname'));
GetServByPort := GetProcAddress(LibHandle, PChar('getservbyport'));
ssGetHostName := GetProcAddress(LibHandle, PChar('gethostname'));
{$IFNDEF FORCEOLDAPI}
GetAddrInfo := GetProcAddress(LibHandle, PChar('getaddrinfo'));
FreeAddrInfo := GetProcAddress(LibHandle, PChar('freeaddrinfo'));
GetNameInfo := GetProcAddress(LibHandle, PChar('getnameinfo'));
SockEnhancedApi := Assigned(GetAddrInfo) and Assigned(FreeAddrInfo)
and Assigned(GetNameInfo);
if not SockEnhancedApi then
begin
LibWship6Handle := LoadLibrary(PChar(DLLWship6));
if LibWship6Handle <> 0 then
begin
GetAddrInfo := GetProcAddress(LibWship6Handle, PChar('getaddrinfo'));
FreeAddrInfo := GetProcAddress(LibWship6Handle, PChar('freeaddrinfo'));
GetNameInfo := GetProcAddress(LibWship6Handle, PChar('getnameinfo'));
SockWship6Api := Assigned(GetAddrInfo) and Assigned(FreeAddrInfo)
and Assigned(GetNameInfo);
end;
end;
{$ENDIF}
Result := True;
end;
end
else Result := True;
if Result then
Inc(SynSockCount);
finally
SynSockCS.Leave;
end;
end;
function DestroySocketInterface: Boolean;
begin
SynSockCS.Enter;
try
Dec(SynSockCount);
if SynSockCount < 0 then
SynSockCount := 0;
if SynSockCount = 0 then
begin
if LibHandle <> 0 then
begin
FreeLibrary(libHandle);
LibHandle := 0;
end;
if LibWship6Handle <> 0 then
begin
FreeLibrary(LibWship6Handle);
LibWship6Handle := 0;
end;
end;
finally
SynSockCS.Leave;
end;
Result := True;
end;
initialization
begin
SynSockCS := SyncObjs.TCriticalSection.Create;
SET_IN6_IF_ADDR_ANY (@in6addr_any);
SET_LOOPBACK_ADDR6 (@in6addr_loopback);
end;
finalization
begin
SynSockCS.Free;
end;
{$ENDIF}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -