zoukankan      html  css  js  c++  java
  • [转]在多线程中使用UDP

    kraft @ 2005-05-10 21:20

    来自:painboy, 时间:2004-8-8 11:34:40, ID:2754268
    type TUdpThread = class(TThread)
     private
       FData     : PChar;        //数据区
       FBytes    : Integer;      //数据区大小
       FFromIP   : string;       //UDP的源地址
       FFromPort : Integer;      //UDP的源端口
     public
       constructor Create(Buffer: PChar; NumberBytes: Integer; FromIP: String; Port: Integer);
     protected
       procedure Execute; override;
    end;



    procedure TForm1.Button1Click(Sender: TObject);
    var Buffer : array[0..1024] of char;
    begin
     strcopy(buffer,pchar(Edit1.Text));
     UdpSend.ReportLevel := Status_Basic;
     UdpSend.RemotePort := 4000;
     UdpSend.RemoteHost := '127.0.0.1';
     UdpSend.Sendbuffer(buffer,256);
    end;


    constructor TUdpThread.Create(Buffer: PChar; NumberBytes: Integer; FromIP: String; Port: Integer);
    begin
     inherited Create(True);

     FData     := Buffer;
     FBytes    := NumberBytes;
     FFromIP   := FromIP;
     FFromPort := Port;

     FreeOnTerminate := True;
     Resume;
    end;

    procedure TUdpThread.Execute;
    var Buffer : PChar;
       BackTo : array[0..1] of char;
       str    : string;
       myUDP  : TNMUDP;
    begin
     str := inttostr(GetTickCount)+' : ';
     GetMem(Buffer, FBytes+1);
     CopyMemory(Buffer, FData, FBytes);

     Randomize;                              
     Sleep(Random(5000));                    
     Form1.Memo1.Lines.Add(str+Buffer);  
     //其实以上几句改为你自己的处理代码就是了    
     
     FillChar(BackTo, 2, f);
     myUDP := TNMUDP.Create(Nil);
     myUDP.RemoteHost  := FFromIP;
     myUDP.ReportLevel := Status_Basic;
     myUDP.LocalPort   := 4000;

     myUDP.SendBuffer(BackTo, 2);            //回个响应包给对方

     FreeMem(Buffer, FBytes+1);
     FreeMem(FData, FBytes);
    end;

    procedure TForm1.UdpRecvDataReceived(Sender: TComponent;
     NumberBytes: Integer; FromIP: String; Port: Integer);
    var Buffer : PChar ;
    begin
     GetMem(Buffer, NumberBytes);
     UdpRecv.ReadBuffer(Buffer^, NumberBytes);                //接收数据
     TUdpThread.Create(Buffer, NumberBytes, FromIP, Port);    //将数据交给子线程处理
    end;

    procedure TForm1.UdpSendDataReceived(Sender: TComponent;
     NumberBytes: Integer; FromIP: String; Port: Integer);
    var Buffer : PChar ;
    begin
     GetMem(Buffer, NumberBytes);
     UdpSend.ReadBuffer(Buffer^, NumberBytes);
     FreeMem(Buffer, NumberBytes);
    end;


    来自:painboy, 时间:2004-8-8 13:56:05, ID:2754370
    SORRY,看错题了。你是说要在线程里收发数据。用API重写了一下,D5下通过了。

    type TUdpThread = class(TThread)
     private
       FSocket : TSocket;
     public
       constructor Create;
     protected
       procedure Execute; override;
       function CanRead(Socket : TSocket; Timeout: Integer): Boolean;
    end;


    constructor TUdpThread.Create;
    begin
     inherited Create(True);
     FreeOnTerminate := True;
     Resume;
    end;

    function TUdpThread.CanRead(Timeout: Integer): Boolean;
    var
     TimeV: TTimeVal;
     FDSet: TFDSet;
     X    : integer;
    begin
     TimeV.tv_usec := (Timeout mod 1000) * 1000;
     TimeV.tv_sec := Timeout div 1000;
     FDSet.fd_count := 1;
     FDSet.fd_array[0] := FSocket;
     X := Select(0, @FDSet, nil, nil, @TimeV);
     Result := X>0;
    end;

    procedure TUdpThread.Execute;
    var
     wsaD      : WSADATA;
     sa        : TSockAddrIn;
     nLen,nFrom: Integer;
     UdpBuffer : array[0..1023] of Char;
    begin
     WSAStartup(01, wsaD);
     FSocket := Socket(AF_INET, SOCK_DGRAM, 0);
     if (FSocket <> INVALID_SOCKET) then begin
       sa.sin_family:= AF_INET;
       sa.sin_port:= htons(4096);
       sa.sin_addr.S_addr:= inet_addr('127.0.0.1');
       nLen:= SizeOf(sa);
       bind(FSocket, sa, nLen);
       While not Terminated do
         if CanRead(10) then begin                                 //检查是否有数据可接收
           FillChar(UdpBuffer, 1024, 0);
           nFrom := SizeOf(sa);
           RecvFrom(FSocket, UdpBuffer, nLen, 0, sa, nFrom);       //接收数据

           Form1.Memo1.Lines.Add(inet_ntoa(sa.sin_addr)+' : '+UdpBuffer);

           FillChar(UdpBuffer, 2, f);
           nFrom := SizeOf(sa);
           SendTo(FSocket, UdpBuffer, 2, 0, sa, nFrom);            //应答
         end  else begin
           //暂时没有数据来,你可以干点别的事情  :)
         end;
       CloseSocket(FSocket);
     end;
     WSACleanUp;
    end;


    //////////////////////////////////////////////////////////////////////////////////////////
    //                                                                                      //
    //        上面的线程是用WINSOCKET API写的,没做差错检查,但你说的功能已经实现           //
    //                                                                                      //
    //////////////////////////////////////////////////////////////////////////////////////////


    procedure TForm1.Button1Click(Sender: TObject);              //这里 UdpSend是个TNMUDP控件
    var Buffer : array[0..1024] of char;
    begin
       strcopy(buffer,'Hello!');
       UdpSend.ReportLevel := Status_Basic;
       UdpSend.RemotePort := 4096;
       UdpSend.RemoteHost := '127.0.0.1';
       UdpSend.Sendbuffer(buffer,256);
    end;

    procedure TForm1.UdpSendDataReceived(Sender: TComponent;
     NumberBytes: Integer; FromIP: String; Port: Integer);
    var Buffer : PChar ;
    begin
     GetMem(Buffer, NumberBytes);
     UdpSend.ReadBuffer(Buffer^, NumberBytes);
     FreeMem(Buffer, NumberBytes);
     Memo1.Lines.Add(Inttostr(NumberBytes)+ ' Bytes');
    end;


    来自:乡村月光, 时间:2004-8-8 14:45:58, ID:2754430
    我有API的代码,一个转发服务器,一个队列发送器,一个队列接收器,用起来很方便,有人要就贴

    来自:乡村月光, 时间:2004-8-9 22:23:59, ID:2756448

    unit UDPNet;

    interface
    uses Windows, Messages, SysUtils, Variants, Classes, Winsock;

    // 为了提高效率,本单元所有的地址都使用winsock内部格式,和习惯IP之间用AddrToIP和IPToAdr转换!
    const
     UDPACKETSIZE = 512; // 最大UDP包大小
     UDPXHEADSIZE = 8;   // 数据包头大小
     UDPXDATASIZE = UDPACKETSIZE - UDPXHEADSIZE ; // 最大数据包大小

     UDPXDATAFLAG = AC5; // 转发数据包头标志

     WM_TERMINATE = WM_USER + 100; // 结束线程
     WM_SENDDATA  = WM_USER + 101; // 发送数据

    type
     TSyncSignal = class(TObject) // 线程安全信号
     private
       FSignal: Boolean;
       FCritical: _RTL_CRITICAL_SECTION;
       function GetSignal: Boolean;
     public
       constructor Create(IniState: Boolean);
       destructor Destroy; override;
       procedure Reset;
       property IsSafe: Boolean read GetSignal;
     end;

     ESocketError = class(Exception);

     TSyncUDPSocket = class(TObject) // 封装API
     protected
       FHandle: TSocket;
       FLastError: Integer;
       function GetBroadcast: Boolean;
       function GetReuseAddr: Boolean;
       function GetRecvBufSize: Integer;
       function GetSendBufSize: Integer;
       procedure SetBroadcast(Value: Boolean);
       procedure SetReuseAddr(Value: Boolean);
       procedure SetRecvBufSize(Value: Integer);
       procedure SetSendBufSize(Value: Integer);
     public
       constructor Create;
       destructor Destroy; override;
       function RecvBuffer(var Buffer; Len: Integer): Integer;
       function RecvFrom(var Buffer; Len: Integer; var Addr: Integer; var Port: Word): Integer;
       function ByteCanRead: Integer;
       function SendBuffer(var Buffer; Len: Integer): Integer;
       function SendTo(Addr: Integer; Port: Word; var Buffer; Len: Integer): Integer;
       function WaitForData(TimeOut: Integer): Boolean;
       procedure Bind(Addr: Integer; Port: Word);
       procedure Connect(Addr: Integer; Port: Word);
       procedure CreateSocket;
       procedure GetLocalHost(var IP: string; var Port: Word);
       procedure GetRemoteHost(var IP: string; var Port: Word);
       property Broadcast: Boolean read GetBroadcast write SetBroadcast;
       property Handle: TSocket read FHandle write FHandle;
       property LastError: Integer read FLastError;
       property ReuseAddr: Boolean read GetReuseAddr write SetReuseAddr;
       property SizeRecvBuffer: Integer read GetRecvBufSize write SetRecvBufSize;
       property SizeSendBuffer: Integer read GetSendBufSize write SetSendBufSize;
     end;

     TUDPXDataBuffer = packed record // 转发数据包
       Flag: Word;
       Port: Word;
       Addr: Integer;
       Data: array [0..UDPXDATASIZE-1] of Byte;
     end;

     TUDPXServerThread = class(TThread) // 数据转发服务器
     protected
       FUDPSock: TSyncUDPSocket;
       FUDPort: Word;
     public
       constructor Create(Port: Word);
       destructor Destroy; override;
       procedure Execute; override;
     end;

     TUDPQueData = packed record  // 队列数据
       Addr: Integer;
       Port: Word;
       Len: Word;
       Data: array [0..UDPACKETSIZE-1] of Byte;
     end;
     TUDPQueBuffer = array [0..1] of TUDPQueData;
     PUDPQueBuffer = ^TUDPQueBuffer;

     TUDPDataQue = record // 队列
       Header, Tail, BufSize: Integer;
       IsFull: Boolean;
       Queue: PUDPQueBuffer;
     end;

     TUDPReceiver = class;
     TUDPDataNotify = procedure(Sender: TUDPReceiver; const Data: TUDPQueData) of object;

     TUDPReceiver = class(TThread) // 接收器
     protected
       FUDPSock: TSyncUDPSocket;
       FOnData: TUDPDataNotify;
     public
       constructor Create(Sock: TSyncUDPSocket);
       procedure Execute; override;
       property OnData: TUDPDataNotify read FOnData write FOnData;
       property UDPSock: TSyncUDPSocket read FUDPSock write FUDPSock;
     end;

     TUDPQueSender = class(TThread) // 队列发送器,通过消息WM_TERMINATE结束
     protected
       FUDPSock: TSyncUDPSocket;
       FBuffer: TUDPDataQue;
       FSync: TSyncSignal;
     public
       constructor Create(Sock: TSyncUDPSocket; BufSize: Integer);
       destructor Destroy; override;
       function AddData(Addr: Integer; Port: Word; const Header; HLen: Word;
                const Data; DLen: Word): Boolean; // 要发送数据调用本函数
       procedure Execute; override;
       property Buffer: TUDPDataQue read FBuffer;
       property UDPSock: TSyncUDPSocket read FUDPSock write FUDPSock;
     end;

    function AddrToIP(Addr: Integer): string;
    function IPToAddr(const IP: string): Integer;

    implementation

    constructor TSyncSignal.Create(IniState: Boolean);
    begin
     inherited Create;
     InitializeCriticalSection(FCritical);
     FSignal := IniState;
    end;

    destructor TSyncSignal.Destroy;
    begin
     DeleteCriticalSection(FCritical);
     inherited Destroy;
    end;

    function TSyncSignal.GetSignal: Boolean;
    begin
     EnterCriticalSection(FCritical);
     Result := FSignal;
     FSignal := False;
     LeaveCriticalSection(FCritical);
    end;

    procedure TSyncSignal.Reset;
    begin
     FSignal := True;
    end;

    constructor TSyncUDPSocket.Create;
    begin
     inherited Create;
     FLastError := 0;
     FHandle := INVALID_SOCKET;
    end;

    destructor TSyncUDPSocket.Destroy;
    begin
     if FHandle <> INVALID_SOCKET then CloseSocket(FHandle);
     inherited Destroy;
    end;

    function TSyncUDPSocket.GetBroadcast: Boolean;
    var m, n: Integer;
    begin
     FLastError := 0;
     n := Sizeof(Integer);
     if GetSockOpt(FHandle, SOL_SOCKET, SO_BROADCAST, @m, n) <> 0 then
     begin
       FLastError := WSAGetLastError;
       Result := False;
     end
     else Result := m <> 0;
    end;

    function TSyncUDPSocket.GetReuseAddr: Boolean;
    var m, n: Integer;
    begin
     FLastError := 0;
     n := Sizeof(Integer);
     if GetSockOpt(FHandle, SOL_SOCKET, SO_REUSEADDR, @m, n) <> 0 then
     begin
       FLastError := WSAGetLastError;
       Result := False;
     end
     else Result := m <> 0;
    end;

    function TSyncUDPSocket.GetRecvBufSize: Integer;
    var n: Integer;
    begin
     n := SizeOf(Result);
     FLastError := 0;
     if GetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, @Result, n) <> 0 then
     begin
       FLastError := WSAGetLastError;
       Result := -1;
     end;
    end;

    function TSyncUDPSocket.GetSendBufSize: Integer;
    var n: Integer;
    begin
     n := SizeOf(Result);
     FLastError := 0;
     if GetSockOpt(FHandle, SOL_SOCKET, SO_SNDBUF, @Result, n) <> 0 then
     begin
       FLastError := WSAGetLastError;
       Result := -1;
     end;
    end;

    procedure TSyncUDPSocket.SetBroadcast(Value: Boolean);
    var n: Integer;
    begin
     FLastError := 0;
     if Value then n := -1 else n := 0;
     if SetSockOpt(FHandle, SOL_SOCKET, SO_BROADCAST, @n, SizeOf(Integer)) <> 0 then
       FLastError := WSAGetLastError;
    end;

    procedure TSyncUDPSocket.SetReuseAddr(Value: Boolean);
    var n: Integer;
    begin
     FLastError := 0;
     if Value then n := -1 else n := 0;
     if SetSockOpt(FHandle, SOL_SOCKET, SO_REUSEADDR, @n, SizeOf(Integer)) <> 0 then
       FLastError := WSAGetLastError;
    end;

    procedure TSyncUDPSocket.SetRecvBufSize(Value: Integer);
    begin
     FLastError := 0;
     if SetSockOpt(FHandle, SOL_SOCKET, SO_RCVBUF, @Value, SizeOf(Integer)) <> 0 then
       FLastError := WSAGetLastError;
    end;

    procedure TSyncUDPSocket.SetSendBufSize(Value: Integer);
    begin
     FLastError := 0;
     if SetSockOpt(FHandle, SOL_SOCKET, SO_SNDBUF, @Value, SizeOf(Integer)) <> 0 then
       FLastError := WSAGetLastError;
    end;

    function TSyncUDPSocket.ByteCanRead: Integer;
    var n: Integer;
    begin
     FLastError := 0;
     if IoctlSocket(FHandle, FIONREAD, n) = 0 then Result := n
     else begin
       FLastError := WSAGetLastError;
       Result := 0;
     end;
    end;

    function TSyncUDPSocket.WaitForData(TimeOut: Integer): Boolean;
    var tv: TTimeVal;
       pt: PTimeVal;
       n: Integer;
       fs: TFDSet;
    begin
     if TimeOut < 0 then pt := nil else
     begin
       tv.tv_sec := TimeOut div 1000;
       tv.tv_usec := (TimeOut mod 1000) * 1000;
       pt := @tv;
     end;
     FD_ZERO(fs);
     FD_SET(FHandle, fs);
     n := select(0, @fs, nil, nil, pt);
     if n = SOCKET_ERROR then
     begin
       FLastError := WSAGetLastError;
       n := 0;
     end
     else FLastError := 0;
     Result := n > 0;
    end;

    function TSyncUDPSocket.RecvBuffer(var Buffer; Len: Integer): Integer;
    begin
     FLastError := 0;
     Result := WinSock.recv(FHandle, Buffer, Len, 0);
     if Result = SOCKET_ERROR then FLastError := WSAGetLastError;
    end;

    function TSyncUDPSocket.RecvFrom(var Buffer; Len: Integer; var Addr: Integer; var Port: Word): Integer;
    var a: TSockAddr;
       n: Integer;
    begin
     FLastError := 0;
     Result := WinSock.RecvFrom(FHandle, Buffer, Len, 0, a, n);
     Port := ntohs(a.sin_port);
     Addr := a.sin_addr.s_addr;
     if Result = SOCKET_ERROR then FLastError := WSAGetLastError;
    end;

    function TSyncUDPSocket.SendBuffer(var Buffer; Len: Integer): Integer;
    begin
     FLastError := 0;
     Result := WinSock.send(FHandle, Buffer, Len, 0);
     if Result = SOCKET_ERROR then FLastError := WSAGetLastError;
    end;

    function TSyncUDPSocket.SendTo(Addr: Integer; Port: Word; var Buffer; Len: Integer): Integer;
    var a: TSockAddr;
    begin
     FLastError := 0;
     a.sin_family := AF_INET;
     a.sin_port := htons(Port);
     a.sin_addr.s_addr := Addr;
     Result := WinSock.SendTo(FHandle, Buffer, Len, 0, a, Sizeof(TSockAddr));
     if Result = SOCKET_ERROR then FLastError := WSAGetLastError;
    end;

    procedure TSyncUDPSocket.Bind(Addr: Integer; Port: Word);
    var a: TSockAddr;
    begin
     if FHandle = INVALID_SOCKET then
     begin
       CreateSocket;
       if FLastError <> 0 then Exit;
     end;
     FLastError := 0;
     a.sin_family := AF_INET;
     a.sin_port := htons(Port);
     a.sin_addr.s_addr := Addr;
     if WinSock.Bind(FHandle, a, Sizeof(TSockAddr)) = SOCKET_ERROR then
       FLastError := WSAGetLastError;
    end;

    procedure TSyncUDPSocket.Connect(Addr: Integer; Port: Word);
    var a: TSockAddr;
    begin
     if FHandle = INVALID_SOCKET then
     begin
       CreateSocket;
       if FLastError <> 0 then Exit;
     end;
     FLastError := 0;
     a.sin_family := AF_INET;
     a.sin_port := htons(Port);
     a.sin_addr.s_addr := Addr;
     if WinSock.Connect(FHandle, a, Sizeof(TSockAddr)) = SOCKET_ERROR then
       FLastError := WSAGetLastError;
    end;

    procedure TSyncUDPSocket.CreateSocket;
    begin
     FLastError := 0;
     FHandle := Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
     if FHandle = INVALID_SOCKET then FLastError := WSAGetLastError;
    end;

    procedure TSyncUDPSocket.GetLocalHost(var IP: string; var Port: Word);
    var addr: TSockAddr;
       len: Integer;
    begin
     FillChar(addr, Sizeof(TSockAddr), 0);
     len := Sizeof(TSockAddr);
     GetSockName(FHandle, addr, len);
     IP := inet_ntoa(addr.sin_addr);
     Port := ntohs(addr.sin_port);
    end;

    procedure TSyncUDPSocket.GetRemoteHost(var IP: string; var Port: Word);
    var addr: TSockAddr;
       len: Integer;
    begin
     FillChar(addr, Sizeof(TSockAddr), 0);
     len := Sizeof(TSockAddr);
     GetPeerName(FHandle, addr, len);
     IP := inet_ntoa(addr.sin_addr);
     Port := ntohs(addr.sin_port);
    end;

    constructor TUDPXServerThread.Create(Port: Word);
    begin
     inherited Create(True);
     FUDPort := Port;
    end;

    destructor TUDPXServerThread.Destroy;
    begin
     FUDPSock.Free;
     inherited Destroy;
    end;

    procedure TUDPXServerThread.Execute;
    var n, a: Integer;
       p: Word;
       buf: TUDPXDataBuffer;
    begin
     FUDPSock := TSyncUDPSocket.Create;
     FUDPSock.Bind(0, FUDPort);
     while not Terminated do
     begin
       if FUDPSock.WaitForData(100) then
       begin
         n := FUDPSock.ByteCanRead;
         if n > UDPACKETSIZE then n := UDPACKETSIZE;
         FUDPSock.RecvFrom(buf, n, a, p);
         if (buf.Flag = UDPXDATAFLAG) and (n > UDPXHEADSIZE) then
           FUDPSock.SendTo(buf.Addr, buf.Port, buf.Data, n - UDPXHEADSIZE);
       end;
     end;
    end;

    constructor TUDPReceiver.Create(Sock: TSyncUDPSocket);
    begin
     inherited Create(True);
     FUDPSock := Sock;
     FOnData := nil;
    end;

    procedure TUDPReceiver.Execute;
    var buf: TUDPQueData;
    begin
     while not Terminated do
     begin
       if FUDPSock.WaitForData(100) then with buf do
       begin
         Len := FUDPSock.ByteCanRead;
         if Len > UDPACKETSIZE then Len := UDPACKETSIZE;
         FUDPSock.RecvFrom(Data, Len, Addr, Port);
         if (FUDPSock.FLastError = 0) and Assigned(FOnData) then FOnData(Self, buf);
       end;
     end;
    end;

    constructor TUDPQueSender.Create(Sock: TSyncUDPSocket; BufSize: Integer);
    begin
     inherited Create(True);
     FUDPSock := Sock;
     FBuffer.Header := 0;
     FBuffer.Tail := 0;
     FBuffer.IsFull := False;
     if BufSize < 4 then BufSize := 4;
     FBuffer.BufSize := BufSize;
     GetMem(FBuffer.Queue, FBuffer.BufSize * Sizeof(TUDPQueData));
     FSync := TSyncSignal.Create(True);
     FreeOnTerminate := True;
    end;

    destructor TUDPQueSender.Destroy;
    begin
     FreeMem(FBuffer.Queue, FBuffer.BufSize * Sizeof(TUDPQueData));
     FSync.Free;
     inherited Destroy;
    end;

    function TUDPQueSender.AddData(Addr: Integer; Port: Word; const Header; HLen: Word;
            const Data; DLen: Word): Boolean;
    var i, n: Integer;
    begin
     while not FSync.IsSafe do Sleep(0);
     i := FBuffer.Tail;
     Result := not ((i = FBuffer.Header) and FBuffer.IsFull);
     if Result and ((HLen > 0) or (DLen > 0)) then
     begin
       if HLen > UDPACKETSIZE then HLen := UDPACKETSIZE;
       n := HLen + DLen;
       if n > UDPACKETSIZE then DLen := UDPACKETSIZE - HLen;
       FBuffer.Queue.Addr := Addr;
       FBuffer.Queue.Port := Port;
       FBuffer.Queue.Len := n;
       if HLen > 0 then Move(Header, FBuffer.Queue.Data[0], HLen);
       if DLen > 0 then Move(Data, FBuffer.Queue.Data[HLen], DLen);
       Inc(i);
       if i >= FBuffer.BufSize then i := 0;
       FBuffer.Tail := i;
       FBuffer.IsFull := i = FBuffer.Header;
     end;
     FSync.Reset;
     PostThreadMessage(ThreadID, WM_SENDDATA, 0, 0);
    end;

    procedure TUDPQueSender.Execute;
    var i: Integer;
       ms: MSG;
    begin
     while not Terminated do
     begin
       GetMessage(ms, 0, 0, 0);
       case ms.message of
         WM_SENDDATA: begin
           while (FBuffer.Header <> FBuffer.Tail) or FBuffer.IsFull do
           begin
             i := FBuffer.Header;
             with FBuffer.Queue do
             begin
               if Len > UDPACKETSIZE then Len := UDPACKETSIZE;
               FUDPSock.SendTo(Addr, Port, Data, Len);
               Inc(i);
               if i >= FBuffer.BufSize then i := 0;
               while not FSync.IsSafe do Sleep(0);            
               FBuffer.Header := i;
               FBuffer.IsFull := False;
               FSync.Reset;
             end;
           end;
         end;
         WM_TERMINATE: Terminate;
       end;
     end;
    end;

    function AddrToIP(Addr: Integer): string;
    var a: in_addr absolute Addr;
    begin
     Result := inet_ntoa(a);
    end;

    function IPToAddr(const IP: string): Integer;
    begin
     Result := inet_addr(PChar(IP));
    end;

    var
     WSAData: TWSAData;

    procedure Startup;
    begin
     if WSAStartup(01, WSAData) <> 0 then raise ESocketError.Create('WSAStartup');
    end;

    procedure Cleanup;
    begin
     if WSACleanup <> 0 then raise ESocketError.Create('WSACleanup');
    end;

    initialization
     Startup;

    finalization
     Cleanup;

    end.
  • 相关阅读:
    【Java EE 学习 36】【struts2】【struts2系统验证】【struts2 ognl值栈】【struts2 ongl标签】【struts2 UI标签】【struts2模型驱动和令牌机制】
    【Java EE 学习 35 下】【struts2】【struts2文件上传】【struts2自定义拦截器】【struts2手动验证】
    【Java EE 学习 35 上】【strus2】【类型转换器】【struts2和Servlet API解耦】【国际化问题】【资源文件乱码问题已经解决】
    【Java EE 学习 34】【struts2学习第一天】
    【JavaScript中的正则表达式】
    【Java EE 学习 33 下】【validate表单验证插件】
    【Java EE 学习 33 上】【JQuery样式操作】【JQuery中的Ajax操作】【JQuery中的XML操作】
    【Java EE 学习 32 下】【JQuery】【JQuey中的DOM操作】
    【Java EE 学习 32 上】【JQuery】【选择器】
    【Java EE 学习 31】【JavaScript基础增强】【Ajax基础】【Json基础】
  • 原文地址:https://www.cnblogs.com/LeoWong/p/1932752.html
Copyright © 2011-2022 走看看