📄 uwinsocket.pas
字号:
unit uWinSocket;
interface
uses
Windows, Sysutils, WinSock2, uException, uWin32Const;
type
TWinSocket = class
protected
FSockAddr: TSockAddrIn;
clientSocket: TSocket;
public
//得到本地IP地址
function GetHostIPAddr: String;
//得到远程IP地址
function GetRemoteIPAddr(FRemoteAddr: TSockAddrIn): String;
//关闭Socket套接字
function CloseWinSocket(var m_Socket: TSocket): Boolean;
//安全关闭Socket套接字
function AbortiveCloseSocket(var m_Socket: TSocket): Boolean;
//创建Socket套接字
function CreateWSASocket(var m_Socket: TSocket): Boolean;
//创建Socket套接字(TCPOverlap)
function CreateTCPOverlapSocket(var m_Socket: TSocket): Boolean;
//创建Socket套接字(UDPOverlap)
function CreateUDPOverlapSocket(var m_Socket: TSocket): Boolean;
//设置端口复用
function SetSocketReUseAddr(var m_Socket: TSocket): Boolean;
//设置Socket为ListenSocket状态。
function ChangeSocketModeAccept(var m_Socket, m_sListen: TSocket): Boolean;
//设置nagle算法。
function SetSocketNagle(var m_Socket: TSocket; bVal: Boolean = TRUE): Boolean;
//加载扩展函数AcceptEx
function LoadAcceptEx(var m_Socket: TSocket; var m_lpfnAcceptEx: LPFN_ACCEPTEX): Boolean;
//加载扩展函数GetAcceptExSockaddrs
function LoadAcceptExSockaddrs(var m_Socket: TSocket; var m_lpfnGetAcceptExSockaddrs: LPFN_GETACCEPTEXSOCKADDRS): Boolean;
function BindSocket(var m_Socket: TSocket; m_nPort: Integer): Boolean; overload;
function BindSocket(var m_Socket: TSocket; const strIPAddr: String; m_nPort: Integer): Boolean; overload;
function ListenSocket(var m_Socket: TSocket): Boolean;
function Connect(var m_Socket: TSocket; strIPAddr: String; nPort: DWORD): Boolean;
public
constructor Create;
destructor Destroy; override;
end;
implementation
constructor TWinSocket.Create;
begin
inherited Create;
end;
destructor TWinSocket.Destroy;
begin
inherited Destroy;
end;
function TWinSocket.GetHostIPAddr: String;
var
pHostE: PHostEnt;
Buffer: array[0..100] of char;
begin
Result := '127.0.0.1';
GetHostName(Buffer, Sizeof(Buffer));
pHostE := GetHostByName(Buffer);
if pHostE<> nil then
Result := StrPas(inet_ntoa(PInAddr(pHostE^.h_addr_list^)^));
end;
function TWinSocket.GetRemoteIPAddr(FRemoteAddr: TSockAddrIn): String;
begin
Result := StrPas(inet_ntoa(FRemoteAddr.sin_addr));
end;
function TWinSocket.CloseWinSocket(var m_Socket: TSocket): Boolean;
begin
Result := WinSock2.closesocket(m_Socket) <> SOCKET_ERROR;
m_Socket := INVALID_SOCKET;
end;
function TWinSocket.AbortiveCloseSocket(var m_Socket: TSocket): Boolean;
var
lingerStrt: TLinger;
begin
if m_Socket <> INVALID_SOCKET then begin
Result := FALSE;
Exit;
end;
lingerStrt.l_onoff := 1;
lingerStrt.l_linger := 0;
if WinSock2.setsockopt( m_Socket,
SOL_SOCKET,
SO_LINGER,
@lingerStrt,
sizeof(lingerStrt) ) = SOCKET_ERROR then begin
Result := FALSE;
Exit;
end;
Result := CloseWinSocket(m_Socket);
end;
function TWinSocket.CreateTCPOverlapSocket(var m_Socket: TSocket): Boolean;
begin
//创建socket
m_Socket := Winsock2.WSASocket(AF_INET, SOCK_STREAM, 0, Nil, 0, WSA_FLAG_OVERLAPPED);
if m_Socket = INVALID_SOCKET then begin
Result := FALSE;
end;
Result := TRUE;
end;
function TWinSocket.CreateUDPOverlapSocket(var m_Socket: TSocket): Boolean;
begin
//创建socket
m_Socket := Winsock2.WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, Nil, 0, WSA_FLAG_OVERLAPPED);
if m_Socket = INVALID_SOCKET then begin
Result := FALSE;
end;
Result := TRUE;
end;
function TWinSocket.CreateWSASocket(var m_Socket: TSocket): Boolean;
begin
//创建socket
m_Socket := Winsock2.Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if m_Socket = INVALID_SOCKET then begin
Result := FALSE;
end;
Result := TRUE;
end;
function TWinSocket.SetSocketReUseAddr(var m_Socket: TSocket): Boolean;
var
bVal: LongBool;
nRet: Integer;
begin
//设置端口复用
bVal := True;
nRet := SetSockOpt(m_Socket, SOL_SOCKET, SO_REUSEADDR, PChar(@bVal), SizeOf(bVal));
if (nRet = SOCKET_ERROR) then begin
Result := FALSE;
end;
Result := TRUE;
end;
function TWinSocket.ChangeSocketModeAccept(var m_Socket, m_sListen: TSocket): Boolean;
begin
if (SOCKET_ERROR = setsockopt( m_Socket,
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
Pansichar(@m_sListen),
SizeOf(m_sListen) )) then
begin
CloseWinSocket(m_Socket);
Result := FALSE;
end;
Result := True;
end;
//设置nagle算法。
function TWinSocket.SetSocketNagle(var m_Socket: TSocket; bVal: Boolean = TRUE): Boolean;
begin
//禁止nagle算法bVal := TRUE;
if Winsock2.setsockopt( m_Socket,
IPPROTO_TCP,
TCP_NODELAY,
PChar(@bVal),
SizeOf(bVal) ) = SOCKET_ERROR then begin
CloseWinSocket(m_Socket);
Result := FALSE;
end;
Result := True;
end;
function TWinSocket.LoadAcceptEx(var m_Socket: TSocket; var m_lpfnAcceptEx: LPFN_ACCEPTEX): Boolean;
var
dwBytesReceived: DWORD;
begin
if ( WSAIoctl( m_Socket,
SIO_GET_EXTENSION_FUNCTION_POINTER,
@GuidAcceptEx,
sizeof(GuidAcceptEx),
@@m_lpfnAcceptEx,
sizeof(@m_lpfnAcceptEx),
@dwBytesReceived,
nil,
nil) = SOCKET_ERROR ) then begin
Result := FALSE;
end;
Result := True;
end;
function TWinSocket.LoadAcceptExSockaddrs(var m_Socket: TSocket; var m_lpfnGetAcceptExSockaddrs: LPFN_GETACCEPTEXSOCKADDRS): Boolean;
var
dwBytesReceived: DWORD;
begin
if ( WSAIoctl( m_Socket,
SIO_GET_EXTENSION_FUNCTION_POINTER,
@GuidGetAcceptExSockaddrs,
sizeof(GuidGetAcceptExSockaddrs),
@@m_lpfnGetAcceptExSockaddrs,
sizeof(@m_lpfnGetAcceptExSockaddrs),
@dwBytesReceived,
nil,
nil) = SOCKET_ERROR ) then begin
Result := FALSE;
end;
Result := True;
end;
function TWinSocket.BindSocket(var m_Socket: TSocket; m_nPort: Integer): Boolean;
var
sock_Addr: TSockAddrIn;
begin
FillChar(sock_Addr, SizeOf(sock_Addr), 0);
sock_Addr.sin_family := AF_INET;
sock_Addr.sin_addr.S_addr := INADDR_ANY;
sock_Addr.sin_port := Winsock2.htons(m_nPort);
//绑定套接字
if Bind( m_Socket,
@sock_Addr,
sizeof(sock_Addr) ) = SOCKET_ERROR then begin
CloseWinSocket(m_Socket);
Result := FALSE;
end;
Result := True;
end;
function TWinSocket.BindSocket(var m_Socket: TSocket; const strIPAddr: String; m_nPort: Integer): Boolean;
var
sock_Addr: TSockAddrIn;
begin
FillChar(sock_Addr, SizeOf(sock_Addr), 0);
sock_Addr.sin_family := AF_INET;
sock_Addr.sin_addr.S_addr := Winsock2.inet_addr(PChar(strIPAddr));
sock_Addr.sin_port := Winsock2.htons(m_nPort);
//绑定套接字
if Bind( m_Socket,
@sock_Addr,
sizeof(sock_Addr) ) = SOCKET_ERROR then begin
CloseWinSocket(m_Socket);
Result := FALSE;
end;
Result := True;
end;
function TWinSocket.ListenSocket(var m_Socket: TSocket): Boolean;
begin
//侦听
if Listen(m_Socket, 5) = SOCKET_ERROR then begin
CloseWinSocket(m_Socket);
Result := FALSE;
Exit;
end;
Result := True;
end;
function TWinSocket.Connect(var m_Socket: TSocket; strIPAddr: String; nPort: DWORD): Boolean;
var
nRet: Integer;
FSockAddr: TSockAddrIn;
begin
FillChar(FSockAddr, SizeOf(FSockAddr), 0);
FSockAddr.sin_family := AF_INET;
FSockAddr.sin_addr.S_addr := inet_addr(PChar(strIPAddr));
FSockAddr.sin_port := Winsock2.htons(nPort);
nRet := Winsock2.connect(m_Socket, @FSockAddr, SizeOf(FSockAddr));
if ( (nRet = SOCKET_ERROR) and
(WSAGetLastError()<>WSAEWOULDBLOCK) ) then begin
CloseWinSocket(m_Socket);
Result := FALSE;
end;
Result := TRUE;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -