⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uwinsocket.pas

📁 楠楠写的DBiocp例子都是源码
💻 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 + -