📄 blcksock.pas
字号:
{$IFNDEF ONCEWINSOCK}
synsock.WSACleanup;
DestroySocketInterface;
{$ENDIF}
for n := FDelayedOptions.Count - 1 downto 0 do
begin
p := TSynaOption(FDelayedOptions[n]);
p.Free;
end;
FDelayedOptions.Free;
inherited Destroy;
end;
function TBlockSocket.IsNewApi: Boolean;
begin
Result := SockEnhancedApi;
if not Result then
Result := (FFamily = SF_ip6) and SockWship6Api;
end;
procedure TBlockSocket.SetDelayedOption(const Value: TSynaOption);
var
li: TLinger;
x: integer;
buf: TMemory;
begin
case value.Option of
SOT_Linger:
begin
{$IFDEF CIL}
li := TLinger.Create(Value.Enabled, Value.Value div 1000);
synsock.SetSockOptObj(FSocket, integer(SOL_SOCKET), integer(SO_LINGER), li);
{$ELSE}
li.l_onoff := Ord(Value.Enabled);
li.l_linger := Value.Value div 1000;
buf := @li;
synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_LINGER), buf, SizeOf(li));
{$ENDIF}
end;
SOT_RecvBuff:
begin
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(value.Value);
{$ELSE}
buf := @Value.Value;
{$ENDIF}
synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_RCVBUF),
buf, SizeOf(Value.Value));
end;
SOT_SendBuff:
begin
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(value.Value);
{$ELSE}
buf := @Value.Value;
{$ENDIF}
synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_SNDBUF),
buf, SizeOf(Value.Value));
end;
SOT_NonBlock:
begin
FNonBlockMode := Value.Enabled;
x := Ord(FNonBlockMode);
synsock.IoctlSocket(FSocket, FIONBIO, u_long(x));
end;
SOT_RecvTimeout:
begin
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(value.Value);
{$ELSE}
buf := @Value.Value;
{$ENDIF}
synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_RCVTIMEO),
buf, SizeOf(Value.Value));
end;
SOT_SendTimeout:
begin
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(value.Value);
{$ELSE}
buf := @Value.Value;
{$ENDIF}
synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_SNDTIMEO),
buf, SizeOf(Value.Value));
end;
SOT_Reuse:
begin
x := Ord(Value.Enabled);
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(x);
{$ELSE}
buf := @x;
{$ENDIF}
synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_REUSEADDR), buf, SizeOf(x));
end;
SOT_TTL:
begin
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(value.Value);
{$ELSE}
buf := @Value.Value;
{$ENDIF}
if FIP6Used then
synsock.SetSockOpt(FSocket, integer(IPPROTO_IPV6), integer(IPV6_UNICAST_HOPS),
buf, SizeOf(Value.Value))
else
synsock.SetSockOpt(FSocket, integer(IPPROTO_IP), integer(IP_TTL),
buf, SizeOf(Value.Value));
end;
SOT_Broadcast:
begin
//#todo1 broadcasty na IP6
x := Ord(Value.Enabled);
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(x);
{$ELSE}
buf := @x;
{$ENDIF}
synsock.SetSockOpt(FSocket, integer(SOL_SOCKET), integer(SO_BROADCAST), buf, SizeOf(x));
end;
SOT_MulticastTTL:
begin
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(value.Value);
{$ELSE}
buf := @Value.Value;
{$ENDIF}
if FIP6Used then
synsock.SetSockOpt(FSocket, integer(IPPROTO_IPV6), integer(IPV6_MULTICAST_HOPS),
buf, SizeOf(Value.Value))
else
synsock.SetSockOpt(FSocket, integer(IPPROTO_IP), integer(IP_MULTICAST_TTL),
buf, SizeOf(Value.Value));
end;
SOT_MulticastLoop:
begin
x := Ord(Value.Enabled);
{$IFDEF CIL}
buf := System.BitConverter.GetBytes(x);
{$ELSE}
buf := @x;
{$ENDIF}
if FIP6Used then
synsock.SetSockOpt(FSocket, integer(IPPROTO_IPV6), integer(IPV6_MULTICAST_LOOP), buf, SizeOf(x))
else
synsock.SetSockOpt(FSocket, integer(IPPROTO_IP), integer(IP_MULTICAST_LOOP), buf, SizeOf(x));
end;
end;
Value.free;
end;
procedure TBlockSocket.DelayedOption(const Value: TSynaOption);
begin
if FSocket = INVALID_SOCKET then
begin
FDelayedOptions.Insert(0, Value);
end
else
SetDelayedOption(Value);
end;
procedure TBlockSocket.ProcessDelayedOptions;
var
n: integer;
d: TSynaOption;
begin
for n := FDelayedOptions.Count - 1 downto 0 do
begin
d := TSynaOption(FDelayedOptions[n]);
SetDelayedOption(d);
end;
FDelayedOptions.Clear;
end;
procedure TBlockSocket.SetSin(var Sin: TVarSin; IP, Port: string);
{$IFNDEF CIL}
type
pu_long = ^u_long;
var
ProtoEnt: PProtoEnt;
ServEnt: PServEnt;
HostEnt: PHostEnt;
r: integer;
Hints1, Hints2: TAddrInfo;
Sin1, Sin2: TVarSin;
TwoPass: boolean;
function GetAddr(const IP, port: string; Hints: TAddrInfo; var Sin: TVarSin): integer;
var
Addr: PAddrInfo;
begin
Addr := nil;
try
FillChar(Sin, Sizeof(Sin), 0);
if Hints.ai_socktype = SOCK_RAW then
begin
Hints.ai_socktype := 0;
Hints.ai_protocol := 0;
Result := synsock.GetAddrInfo(PChar(IP), nil, @Hints, Addr);
end
else
begin
if (IP = cAnyHost) or (IP = c6AnyHost) then
begin
Hints.ai_flags := AI_PASSIVE;
Result := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
end
else
if (IP = cLocalhost) or (IP = c6Localhost) then
begin
Result := synsock.GetAddrInfo(nil, PChar(Port), @Hints, Addr);
end
else
begin
Result := synsock.GetAddrInfo(PChar(IP), PChar(Port), @Hints, Addr);
end;
end;
if Result = 0 then
if (Addr <> nil) then
Move(Addr^.ai_addr^, Sin, Addr^.ai_addrlen);
finally
if Assigned(Addr) then
synsock.FreeAddrInfo(Addr);
end;
end;
begin
DoStatus(HR_ResolvingBegin, IP + ':' + Port);
FLastError := 0;
FillChar(Sin, Sizeof(Sin), 0);
if not IsNewApi then
begin
SynSockCS.Enter;
try
Sin.sin_family := AF_INET;
ProtoEnt := synsock.GetProtoByNumber(GetSocketProtocol);
ServEnt := nil;
if ProtoEnt <> nil then
ServEnt := synsock.GetServByName(PChar(Port), ProtoEnt^.p_name);
if ServEnt = nil then
Sin.sin_port := synsock.htons(StrToIntDef(Port, 0))
else
Sin.sin_port := ServEnt^.s_port;
if IP = cBroadcast then
Sin.sin_addr.s_addr := u_long(INADDR_BROADCAST)
else
begin
Sin.sin_addr.s_addr := synsock.inet_addr(PChar(IP));
if Sin.sin_addr.s_addr = u_long(INADDR_NONE) then
begin
HostEnt := synsock.GetHostByName(PChar(IP));
FLastError := synsock.WSAGetLastError;
if HostEnt <> nil then
Sin.sin_addr.S_addr := u_long(Pu_long(HostEnt^.h_addr_list^)^);
end;
end;
finally
SynSockCS.Leave;
end;
end
else
begin
FillChar(Hints1, Sizeof(Hints1), 0);
FillChar(Hints2, Sizeof(Hints2), 0);
TwoPass := False;
//if socket exists, then use their type, else use users selection
if FSocket = INVALID_SOCKET then
case FFamily of
SF_Any:
begin
if IsIP(IP) then
Hints1.ai_family := AF_INET
else
if IsIP6(IP) then
Hints1.ai_family := AF_INET6
else
if FPreferIP4 then
begin
Hints1.ai_family := AF_INET;
Hints2.ai_family := AF_INET6;
TwoPass := True;
end
else
begin
Hints2.ai_family := AF_INET;
Hints1.ai_family := AF_INET6;
TwoPass := True;
end
end;
SF_IP4:
Hints1.ai_family := AF_INET;
SF_IP6:
Hints1.ai_family := AF_INET6;
end
else
if FIP6Used then
Hints1.ai_family := AF_INET6
else
Hints1.ai_family := AF_INET;
Hints1.ai_socktype := GetSocketType;
Hints1.ai_protocol := GetSocketprotocol;
Hints2.ai_socktype := Hints1.ai_socktype;
Hints2.ai_protocol := Hints1.ai_protocol;
r := GetAddr(IP, Port, Hints1, Sin1);
FLastError := r;
sin := sin1;
if r <> 0 then
if TwoPass then
begin
r := GetAddr(IP, Port, Hints2, Sin2);
FLastError := r;
if r = 0 then
sin := sin2;
end;
end;
{$ELSE}
var
IPs: array of IPAddress;
n: integer;
ip4, ip6: string;
sip: string;
begin
ip4 := '';
ip6 := '';
IPs := Dns.Resolve(IP).Addres
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -