delphimvcframework/lib/crosssocket/Net.RawSocket.pas

174 lines
5.0 KiB
ObjectPascal
Raw Normal View History

unit Net.RawSocket;
interface
uses
System.SysUtils, Net.SocketAPI,
{$IFDEF POSIX}
Posix.Base, Posix.SysSocket, Posix.NetinetIn
{$ELSE}
Winapi.Windows, Net.Winsock2, Net.Wship6
{$ENDIF};
type
/// <summary>
/// <20>򵥵<EFBFBD><F2B5A5B5>׽<EFBFBD><D7BD>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
TRawSocket = class
private
FSocket: THandle;
FSockAddr: TRawSockAddrIn;
FPeerAddr: string;
FPeerPort: Word;
public
/// <summary>
/// <20>ر<EFBFBD> Socket
/// </summary>
procedure Close;
/// <summary>
/// <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD>, ֧<><D6A7> IPv6
/// </summary>
function Connect(const AHost: string; APort: Word): Integer;
/// <summary>
/// <20><><EFBFBD><EFBFBD> Socket <20><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD>Ͷ˿<CDB6>, ֧<><D6A7> IPv6
/// </summary>
function Bind(const Addr: string; APort: Word): Integer;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
function Listen(backlog: Integer = SOMAXCONN): Integer;
/// <summary>
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Socket
/// </summary>
function Accept(Addr: PSockAddr; AddrLen: PInteger): THandle;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
function Recv(var Buf; len: Integer; flags: Integer = 0): Integer;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
function Send(const Buf; len: Integer; flags: Integer = 0): Integer;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD>˿<EFBFBD>(<28><><EFBFBD><EFBFBD>UDP)
/// </summary>
function RecvFrom(const Addr: PSockAddr; var AddrLen: Integer; var Buf;
len: Integer; flags: Integer = 0): Integer;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD>˿<EFBFBD>(<28><><EFBFBD><EFBFBD>UDP)
/// </summary>
function SendTo(const Addr: PSockAddr; AddrLen: Integer; const Buf;
len: Integer; flags: Integer = 0): Integer;
/// <summary>
/// <20>ж<EFBFBD><D0B6>׽<EFBFBD><D7BD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
/// </summary>
function IsValid: Boolean;
/// <summary>
/// <20>׽<EFBFBD><D7BD>־<EFBFBD><D6BE><EFBFBD>
/// </summary>
property Socket: THandle read FSocket;
/// <summary>
/// <20>׽<EFBFBD><D7BD>ֵ<EFBFBD>ַ<EFBFBD><D6B7>Ϣ
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Connect <20><>Զ<EFBFBD>˵<EFBFBD><CBB5>׽<EFBFBD><D7BD><EFBFBD>, <20><><EFBFBD>õ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD>˵<EFBFBD>ַ<EFBFBD><D6B7>Ϣ
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Bind <20><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5>׽<EFBFBD><D7BD><EFBFBD>, <20><><EFBFBD>õ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DZ<EFBFBD><C7B1>ص<EFBFBD>ַ<EFBFBD><D6B7>Ϣ
/// </summary>
property SockAddr: TRawSockAddrIn read FSockAddr;
property PeerAddr: string read FPeerAddr;
property PeerPort: Word read FPeerPort;
end;
implementation
{ TRawSocket }
procedure TRawSocket.Close;
begin
if (FSocket = INVALID_HANDLE_VALUE) then Exit;
TSocketAPI.CloseSocket(FSocket);
FSocket := INVALID_HANDLE_VALUE;
end;
function TRawSocket.Connect(const AHost: string; APort: Word): Integer;
var
LHints: TRawAddrInfo;
LAddrInfo: PRawAddrInfo;
begin
FillChar(LHints, SizeOf(TRawAddrInfo), 0);
LHints.ai_family := AF_UNSPEC;
LHints.ai_socktype := SOCK_STREAM;
LHints.ai_protocol := IPPROTO_TCP;
LAddrInfo := TSocketAPI.GetAddrInfo(AHost, APort.ToString, LHints);
if (LAddrInfo = nil) then Exit(-1);
try
FSocket := TSocketAPI.NewSocket(LAddrInfo.ai_family, LAddrInfo.ai_socktype,
LAddrInfo.ai_protocol);
if (FSocket = INVALID_HANDLE_VALUE) then Exit(-1);
FSockAddr.AddrLen := LAddrInfo.ai_addrlen;
Move(LAddrInfo.ai_addr^, FSockAddr.Addr, LAddrInfo.ai_addrlen);
TSocketAPI.ExtractAddrInfo(@FSockAddr.Addr, FSockAddr.AddrLen, FPeerAddr, FPeerPort);
TSocketAPI.SetKeepAlive(FSocket, 5, 3, 5);
Result := TSocketAPI.Connect(FSocket, @FSockAddr.Addr, FSockAddr.AddrLen);
finally
TSocketAPI.FreeAddrInfo(LAddrInfo);
end;
end;
function TRawSocket.Bind(const Addr: string; APort: Word): Integer;
var
LHints: TRawAddrInfo;
LAddrInfo: PRawAddrInfo;
begin
FillChar(LHints, SizeOf(TRawAddrInfo), 0);
LHints.ai_family := AF_UNSPEC;
LHints.ai_socktype := SOCK_STREAM;
LHints.ai_protocol := IPPROTO_TCP;
LAddrInfo := TSocketAPI.GetAddrInfo(Addr, APort.ToString, LHints);
if (LAddrInfo = nil) then Exit(-1);
FSockAddr.AddrLen := LAddrInfo.ai_addrlen;
Move(LAddrInfo.ai_addr^, FSockAddr.Addr, LAddrInfo.ai_addrlen);
TSocketAPI.FreeAddrInfo(LAddrInfo);
TSocketAPI.ExtractAddrInfo(@FSockAddr.Addr, FSockAddr.AddrLen, FPeerAddr, FPeerPort);
Result := TSocketAPI.Bind(FSocket, @FSockAddr.Addr, FSockAddr.AddrLen);
end;
function TRawSocket.Listen(backlog: Integer): Integer;
begin
Result := TSocketAPI.Listen(FSocket, backlog);
end;
function TRawSocket.Accept(Addr: PSockAddr; AddrLen: PInteger): THandle;
begin
Result := TSocketAPI.Accept(FSocket, Addr, AddrLen);
end;
function TRawSocket.Recv(var Buf; len, flags: Integer): Integer;
begin
Result := TSocketAPI.Recv(FSocket, Buf, len, flags);
end;
function TRawSocket.Send(const Buf; len, flags: Integer): Integer;
begin
Result := TSocketAPI.Send(FSocket, Buf, len, flags);
end;
function TRawSocket.RecvFrom(const Addr: PSockAddr; var AddrLen: Integer;
var Buf; len, flags: Integer): Integer;
begin
Result := TSocketAPI.RecvFrom(FSocket, Addr, AddrLen, Buf, len, flags);
end;
function TRawSocket.SendTo(const Addr: PSockAddr; AddrLen: Integer; const Buf;
len: Integer; flags: Integer): Integer;
begin
Result := TSocketAPI.SendTo(FSocket, Addr, AddrLen, Buf, len, flags);
end;
function TRawSocket.IsValid: Boolean;
begin
Result := TSocketAPI.IsValidSocket(FSocket);
end;
end.