| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741 |
- {******************************************************************************}
- { CnPack For Delphi/C++Builder }
- { 中国人自己的开放源码第三方开发包 }
- { (C)Copyright 2001-2018 CnPack 开发组 }
- { ------------------------------------ }
- { }
- { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
- { 改和重新发布这一程序。 }
- { }
- { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
- { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
- { }
- { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
- { 还没有,可访问我们的网站: }
- { }
- { 网站地址:http://www.cnpack.org }
- { 电子邮件:master@cnpack.org }
- { }
- {******************************************************************************}
- unit CnUDP;
- {* |<PRE>
- ================================================================================
- * 软件名称:网络通讯组件包
- * 单元名称:UDP 通讯单元
- * 单元作者:周劲羽 (zjy@cnpack.org)
- * 备 注:定义了 TCnUDP,使用非阻塞方式进行 UDP 通讯,支持广播
- * 开发平台:PWin2000Pro + Delphi 5.01
- * 兼容测试:PWin9X/2000/XP + Delphi 5/6/7 + C++Builder 5/6
- * 本 地 化:该单元中的字符串均符合本地化处理方式
- * 单元标识:$Id$
- * 修改记录:2008.11.28 V1.1
- * 加入一控制接收缓冲区大小的属性
- * 2003.11.21 V1.0
- * 创建单元
- ================================================================================
- |</PRE>}
- interface
- {$I CnPack.inc}
- uses
- Windows, Messages, Classes, SysUtils, WinSock, Forms, contnrs;
- const
- csDefRecvBuffSize = 4096;
- csDefUDPSendBuffSize = 256 * 1024;
- csDefUDPRecvBuffSize = 256 * 1024;
- type
- //==============================================================================
- // UDP 通讯类
- //==============================================================================
- { TCnUDP }
- TOnReceive = procedure(Sender: TComponent; Buffer: Pointer; Len: Integer;
- FromIP: string; Port: Integer) of object;
- {* 接收到数据事件
- |<PRE>
- Sender - TCnUDP 对象
- Buffer - 数据缓冲区
- Len - 数据缓冲区长度
- FromIP - 数据来源 IP
- Port - 数据来源端口号
- |</PRE>}
- TCnUDP = class(TComponent)
- {* 使用非阻塞方式进行 UDP 通讯的类。支持广播、数据队列等。}
- private
- FRemoteHost: string;
- FRemotePort: Integer;
- FLocalPort: Integer;
- FSocketWindow: HWND;
- FOnDataReceived: TOnReceive;
- FListening: Boolean;
- Wait_Flag: Boolean;
- RemoteAddress: TSockAddr;
- RemoteHostS: PHostEnt;
- Succeed: Boolean;
- Procing: Boolean;
- EventHandle: THandle;
- ThisSocket: TSocket;
- Queue: TQueue;
- FLastError: Integer;
- FRecvBufSize: Cardinal;
- FRecvBuf: Pointer;
- FBindAddr: string;
- FSockCount: Integer;
- FUDPSendBufSize: Cardinal;
- FUDPRecvBufSize: Cardinal;
- procedure WndProc(var Message: TMessage);
- function ResolveRemoteHost(ARemoteHost: string): Boolean;
- procedure SetLocalPort(NewLocalPort: Integer);
- procedure ProcessIncomingdata;
- procedure ProcessQueue;
- procedure FreeQueueItem(P: Pointer);
- function GetQueueCount: Integer;
- procedure SetupLastError;
- function GetLocalHost: string;
- procedure UpdateBinding;
- procedure SetRecvBufSize(const Value: Cardinal);
- procedure SetBindAddr(const Value: string);
- function SockStartup: Boolean;
- procedure SockCleanup;
- procedure SetUDPRecvBufSize(const Value: Cardinal);
- procedure SetUDPSendBufSize(const Value: Cardinal);
- protected
- procedure Wait;
- procedure Loaded; override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- function SendStream(DataStream: TStream; BroadCast: Boolean = False): Boolean;
- {* 发送一个数据流。如果 BroadCase 为真,执行 UDP 广播,否则发送数据到
- RomoteHost 的机器上的 RemotePort 端口}
- function SendBuffer(Buff: Pointer; Length: Integer; BroadCast:
- Boolean = False): Boolean;
- {* 发送一个数据块。如果 BroadCase 为真,执行 UDP 广播,否则发送数据到
- RomoteHost 的机器上的 RemotePort 端口}
- procedure ClearQueue;
- {* 清空数据队列。如果用户来不及处理接收到的数据,组件会把新数据包放到数据
- 队列中,调用该方法可清空数据队列}
- procedure ProcessRecv;
- {* 处理该 UDP 接口的接收内容。由于 CnUDP 组件的 OnDataReceived 是在主线程
- 消息处理中调用的,如果主线程代码需要等待 UDP 接收而不希望处理所有消息,
- 可以调用该函数。}
- property LastError: Integer read FLastError;
- {* 最后一次错误的错误号,只读属性}
- property Listening: Boolean read FListening;
- {* 表示当前是否正在监听本地端口,只读属性}
- property QueueCount: Integer read GetQueueCount;
- {* 当前数据队列的长度,只读属性}
- property BindAddr: string read FBindAddr write SetBindAddr;
- {* 绑定本地地址}
- published
- property RemoteHost: string read FRemoteHost write FRemoteHost;
- {* 要发送 UDP 数据的目标主机地址}
- property RemotePort: Integer read FRemotePort write FRemotePort;
- {* 要发送 UDP 数据的目标主机端口号}
- property LocalHost: string read GetLocalHost;
- {* 返回本机 IP 地址,只读属性}
- property LocalPort: Integer read FLocalPort write SetLocalPort;
- {* 本地监听的端口号}
- property RecvBufSize: Cardinal read FRecvBufSize write SetRecvBufSize default csDefRecvBuffSize;
- {* 接收的数据缓冲区大小}
- property UDPSendBufSize: Cardinal read FUDPSendBufSize write SetUDPSendBufSize default csDefUDPSendBuffSize;
- {* UDP 发送的数据缓冲区大小}
- property UDPRecvBufSize: Cardinal read FUDPRecvBufSize write SetUDPRecvBufSize default csDefUDPRecvBuffSize;
- {* UDP 接收的数据缓冲区大小}
- property OnDataReceived: TOnReceive read FOnDataReceived write
- FOnDataReceived;
- {* 接收到 UDP 数据包事件}
- end;
- // 取广播地址
- procedure GetBroadCastAddress(sInt: TStrings);
- // 取本机IP地址
- procedure GetLocalIPAddress(sInt: TStrings);
- implementation
- {$R-}
- //==============================================================================
- // 辅助过程
- //==============================================================================
- // 从Winsock 2.0导入函数WSAIOCtl
- function WSAIoctl(s: TSocket; cmd: DWORD; lpInBuffer: PCHAR; dwInBufferLen:
- DWORD;
- lpOutBuffer: PCHAR; dwOutBufferLen: DWORD;
- lpdwOutBytesReturned: LPDWORD;
- lpOverLapped: POINTER;
- lpOverLappedRoutine: POINTER): Integer; stdcall; external 'WS2_32.DLL';
- const
- SIO_GET_INTERFACE_LIST = $4004747F;
- IFF_UP = $00000001;
- IFF_BROADCAST = $00000002;
- IFF_LOOPBACK = $00000004;
- IFF_POINTTOPOINT = $00000008;
- IFF_MULTICAST = $00000010;
- type
- sockaddr_gen = packed record
- AddressIn: sockaddr_in;
- filler: packed array[0..7] of AnsiChar;
- end;
- INTERFACE_INFO = packed record
- iiFlags: u_long; // Interface flags
- iiAddress: sockaddr_gen; // Interface address
- iiBroadcastAddress: sockaddr_gen; // Broadcast address
- iiNetmask: sockaddr_gen; // Network mask
- end;
- // 取广播地址
- procedure DoGetIPAddress(sInt: TStrings; IsBroadCast: Boolean);
- var
- s: TSocket;
- wsaD: WSADATA;
- NumInterfaces: Integer;
- BytesReturned, SetFlags: u_long;
- pAddr, pMask, pCast: TInAddr;
- pAddrStr: string;
- PtrA: pointer;
- Buffer: array[0..20] of INTERFACE_INFO;
- i: Integer;
- begin
- WSAStartup($0101, wsaD); // Start WinSock
- s := Socket(AF_INET, SOCK_STREAM, 0); // Open a socket
- if (s = INVALID_SOCKET) then
- exit;
- try // Call WSAIoCtl
- PtrA := @bytesReturned;
- if (WSAIoCtl(s, SIO_GET_INTERFACE_LIST, nil, 0, @Buffer, 1024, PtrA, nil,
- nil) <> SOCKET_ERROR) then
- begin // If ok, find out how
- // many interfaces exist
- NumInterfaces := BytesReturned div SizeOf(INTERFACE_INFO);
- sInt.Clear;
- for i := 0 to NumInterfaces - 1 do // For every interface
- begin
- SetFlags := Buffer[i].iiFlags;
- if (SetFlags and IFF_BROADCAST = IFF_BROADCAST) and not
- (SetFlags and IFF_LOOPBACK = IFF_LOOPBACK) then
- begin
- pAddr := Buffer[i].iiAddress.AddressIn.sin_addr;
- pMask := Buffer[i].iiNetmask.AddressIn.sin_addr;
- if IsBroadCast then
- begin
- pCast.S_addr := pAddr.S_addr or not pMask.S_addr;
- pAddrStr := string(inet_ntoa(pCast));
- end
- else
- begin
- pAddrStr := string(inet_ntoa(pAddr));
- end;
-
- if sInt.IndexOf(pAddrStr) < 0 then
- sInt.Add(pAddrStr);
- end;
- end;
- end;
- except
- ;
- end;
- CloseSocket(s);
- WSACleanUp;
- end;
- // 取本机IP地址
- procedure GetLocalIPAddress(sInt: TStrings);
- begin
- DoGetIPAddress(sInt, False);
- end;
- // 取广播地址
- procedure GetBroadCastAddress(sInt: TStrings);
- begin
- DoGetIPAddress(sInt, True);
- end;
- //==============================================================================
- // UDP 通讯类
- //==============================================================================
- { TCnUDP }
- const
- WM_ASYNCHRONOUSPROCESS = WM_USER + 101;
- Const_cmd_true = 'TRUE';
- type
- PRecvDataRec = ^TRecvDataRec;
- TRecvDataRec = record
- FromIP: string[128];
- FromPort: u_short;
- Buff: Pointer;
- BuffSize: Integer;
- end;
- constructor TCnUDP.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- Queue := TQueue.Create;
- FListening := False;
- Procing := False;
- FRecvBufSize := csDefRecvBuffSize;
- FUDPSendBufSize := csDefUDPSendBuffSize;
- FUDPRecvBufSize := csDefUDPRecvBuffSize;
- FBindAddr := '0.0.0.0';
- GetMem(RemoteHostS, MAXGETHOSTSTRUCT);
- FSocketWindow := AllocateHWND(WndProc);
- EventHandle := CreateEvent(nil, True, False, '');
- if SockStartup then
- begin
- ThisSocket := Socket(AF_INET, SOCK_DGRAM, 0);
- if ThisSocket = TSocket(INVALID_SOCKET) then
- begin
- SetupLastError;
- SockCleanup;
- Exit;
- end;
- setsockopt(ThisSocket, SOL_SOCKET, SO_DONTLINGER, Const_cmd_true, 4);
- setsockopt(ThisSocket, SOL_SOCKET, SO_BROADCAST, Const_cmd_true, 4);
- FListening := True;
- end;
- end;
- destructor TCnUDP.Destroy;
- begin
- if FRecvBuf <> nil then
- begin
- FreeMem(FRecvBuf);
- FRecvBuf := nil;
- end;
- ClearQueue;
- Queue.Free;
- FreeMem(RemoteHostS, MAXGETHOSTSTRUCT);
- DeallocateHWND(FSocketWindow);
- CloseHandle(EventHandle);
- if ThisSocket <> 0 then
- closesocket(ThisSocket);
- if FListening then
- SockCleanup;
- inherited Destroy;
- end;
- procedure TCnUDP.UpdateBinding;
- var
- Data: DWORD;
- Addr: TSockAddr;
- begin
- if not (csDesigning in ComponentState) then
- begin
- FListening := False;
- if ThisSocket <> 0 then
- begin
- closesocket(ThisSocket);
- SockCleanup;
- end;
- if SockStartup then
- begin
- ThisSocket := Socket(AF_INET, SOCK_DGRAM, 0);
- if ThisSocket = TSocket(INVALID_SOCKET) then
- begin
- SockCleanup;
- SetupLastError;
- Exit;
- end;
- end;
- FillChar(Addr, SizeOf(Addr), 0);
- Addr.sin_addr.S_addr := Inet_Addr(PAnsiChar(AnsiString(FBindAddr)));
- Addr.sin_family := AF_INET;
- Addr.sin_port := htons(FLocalPort);
- Wait_Flag := False;
- if WinSock.Bind(ThisSocket, Addr, SizeOf(Addr)) =
- SOCKET_ERROR then
- begin
- SetupLastError;
- SockCleanup;
- Exit;
- end;
- // Allow to send to 255.255.255.255
- Data := 1;
- WinSock.setsockopt(ThisSocket, SOL_SOCKET, SO_BROADCAST,
- PAnsiChar(@Data), SizeOf(Data));
- Data := FUDPSendBufSize;
- WinSock.setsockopt(ThisSocket, SOL_SOCKET, SO_SNDBUF,
- PAnsiChar(@Data), SizeOf(Data));
- Data := FUDPRecvBufSize;
- WinSock.setsockopt(ThisSocket, SOL_SOCKET, SO_RCVBUF,
- PAnsiChar(@Data), SizeOf(Data));
- WSAAsyncSelect(ThisSocket, FSocketWindow, WM_ASYNCHRONOUSPROCESS, FD_READ);
- FListening := True;
- end;
- end;
- procedure TCnUDP.Loaded;
- begin
- inherited;
- UpdateBinding;
- end;
- procedure TCnUDP.SetBindAddr(const Value: string);
- begin
- if Value <> FBindAddr then
- begin
- FBindAddr := Value;
- UpdateBinding;
- end;
- end;
- procedure TCnUDP.SetLocalPort(NewLocalPort: Integer);
- begin
- if NewLocalPort <> FLocalPort then
- begin
- FLocalPort := NewLocalPort;
- UpdateBinding;
- end;
- end;
- function TCnUDP.ResolveRemoteHost(ARemoteHost: string): Boolean;
- var
- Buf: array[0..127] of AnsiChar;
- begin
- Result := False;
- if not FListening then Exit;
- try
- RemoteAddress.sin_addr.S_addr := Inet_Addr(PAnsiChar(StrPCopy(Buf, {$IFDEF UNICODE}AnsiString{$ENDIF}(ARemoteHost))));
- if RemoteAddress.sin_addr.S_addr = SOCKET_ERROR then
- begin
- Wait_Flag := False;
- WSAAsyncGetHostByName(FSocketWindow, WM_ASYNCHRONOUSPROCESS, Buf,
- PAnsiChar(RemoteHostS), MAXGETHOSTSTRUCT);
- repeat
- Wait;
- until Wait_Flag;
- if Succeed then
- begin
- with RemoteAddress.sin_addr.S_un_b do
- begin
- s_b1 := remotehostS.h_addr_list^[0];
- s_b2 := remotehostS.h_addr_list^[1];
- s_b3 := remotehostS.h_addr_list^[2];
- s_b4 := remotehostS.h_addr_list^[3];
- end;
- end;
- end;
- except
- ;
- end;
- if RemoteAddress.sin_addr.S_addr <> 0 then
- Result := True;
- if not Result then
- SetupLastError;
- end;
- function TCnUDP.SendStream(DataStream: TStream; BroadCast: Boolean): Boolean;
- var
- Buff: Pointer;
- begin
- GetMem(Buff, DataStream.Size);
- try
- DataStream.Position := 0;
- DataStream.Read(Buff^, DataStream.Size);
- Result := SendBuffer(Buff, DataStream.Size, BroadCast);
- finally
- FreeMem(Buff);
- end;
- end;
- function TCnUDP.SendBuffer(Buff: Pointer; Length: Integer;
- BroadCast: Boolean): Boolean;
- var
- Hosts: TStrings;
- i: Integer;
-
- function DoSendBuffer(Buff: Pointer; Length: Integer; Host: string): Boolean;
- var
- i: Integer;
- begin
- Result := False;
- try
- if not ResolveRemoteHost(Host) then
- Exit;
- RemoteAddress.sin_family := AF_INET;
- RemoteAddress.sin_port := htons(FRemotePort);
- i := SizeOf(RemoteAddress);
- if WinSock.sendto(ThisSocket, Buff^, Length, 0, RemoteAddress, i)
- <> SOCKET_ERROR then
- Result := True
- else
- SetupLastError;
- except
- SetupLastError;
- end;
- end;
- begin
- if BroadCast then
- begin
- Result := False;
- Hosts := TStringList.Create;
- try
- GetBroadCastAddress(Hosts);
- for i := 0 to Hosts.Count - 1 do
- if DoSendBuffer(Buff, Length, Hosts[i]) then
- Result := True;
- finally
- Hosts.Free;
- end;
- end
- else
- Result := DoSendBuffer(Buff, Length, FRemoteHost);
- end;
- function TCnUDP.GetQueueCount: Integer;
- begin
- Result := Queue.Count;
- end;
- procedure TCnUDP.FreeQueueItem(P: Pointer);
- var
- Rec: PRecvDataRec;
- begin
- Rec := PRecvDataRec(P);
- Rec.FromIP := '';
- FreeMem(Rec.Buff);
- FreeMem(Rec);
- end;
- procedure TCnUDP.ClearQueue;
- var
- Rec: PRecvDataRec;
- begin
- while Queue.Count > 0 do
- begin
- Rec := Queue.Pop;
- FreeQueueItem(Rec);
- end;
- end;
- procedure TCnUDP.ProcessQueue;
- var
- Rec: PRecvDataRec;
- begin
- if Procing then Exit;
- Procing := True;
- try
- while Queue.Count > 0 do
- begin
- Rec := Queue.Pop;
- if Assigned(FOnDataReceived) then
- FOnDataReceived(Self, Rec.Buff, Rec.BuffSize, string(Rec.FromIP), Rec.FromPort);
- FreeQueueItem(Rec);
- end;
- finally
- Procing := False;
- end;
- end;
- procedure TCnUDP.ProcessRecv;
- var
- Unicode: Boolean;
- MsgExists: Boolean;
- Msg: TMsg;
- begin
- Unicode := IsWindowUnicode(FSocketWindow);
- if Unicode then
- MsgExists := PeekMessageW(Msg, FSocketWindow, 0, 0, PM_REMOVE)
- else
- MsgExists := PeekMessageA(Msg, FSocketWindow, 0, 0, PM_REMOVE);
- if MsgExists then
- begin
- if Msg.Message <> WM_QUIT then
- begin
- TranslateMessage(Msg);
- if Unicode then
- DispatchMessageW(Msg)
- else
- DispatchMessageA(Msg);
- end;
- end;
- end;
- procedure TCnUDP.WndProc(var Message: TMessage);
- begin
- if FListening then
- begin
- with Message do
- begin
- if Msg = WM_ASYNCHRONOUSPROCESS then
- begin
- if LParamLo = FD_READ then
- begin
- ProcessIncomingdata;
- if not Procing then
- ProcessQueue;
- end
- else
- begin
- Wait_Flag := True;
- if LParamHi > 0 then
- Succeed := False
- else
- Succeed := True;
- end;
- SetEvent(EventHandle);
- end
- else
- Result := DefWindowProc(FSocketWindow, Msg, WParam, LParam);
- end;
- end;
- end;
- procedure TCnUDP.ProcessIncomingdata;
- var
- from: TSockAddr;
- i: Integer;
- Rec: PRecvDataRec;
- IBuffSize: Integer;
- begin
- i := SizeOf(from);
- if FRecvBuf = nil then
- GetMem(FRecvBuf, FRecvBufSize);
- IBuffSize := WinSock.recvfrom(ThisSocket, FRecvBuf^, FRecvBufSize, 0, from, i);
- if (IBuffSize > 0) and Assigned(FOnDataReceived) then
- begin
- GetMem(Rec, SizeOf(TRecvDataRec));
- ZeroMemory(Rec, SizeOf(TRecvDataRec));
- Rec.FromIP := ShortString(Format('%d.%d.%d.%d', [Ord(from.sin_addr.S_un_b.S_b1),
- Ord(from.sin_addr.S_un_b.S_b2), Ord(from.sin_addr.S_un_b.S_b3),
- Ord(from.sin_addr.S_un_b.S_b4)]));
- Rec.FromPort := ntohs(from.sin_port);
- GetMem(Rec.Buff, IBuffSize);
- Rec.BuffSize := IBuffSize;
- CopyMemory(Rec.Buff, FRecvBuf, IBuffSize);
- Queue.Push(Rec);
- end;
- end;
- procedure WaitforSync(Handle: THandle);
- begin
- repeat
- if MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLINPUT)
- = WAIT_OBJECT_0 + 1 then
- Application.ProcessMessages
- else
- Break;
- until False;
- end;
- procedure TCnUDP.Wait;
- begin
- WaitforSync(EventHandle);
- ResetEvent(EventHandle);
- end;
- procedure TCnUDP.SetupLastError;
- begin
- FLastError := WSAGetLastError;
- end;
- procedure TCnUDP.SockCleanup;
- begin
- if FSockCount > 0 then
- begin
- Dec(FSockCount);
- if FSockCount = 0 then
- WSACleanup;
- end;
- end;
- function TCnUDP.SockStartup: Boolean;
- var
- wsaData: TWSAData;
- begin
- if FSockCount = 0 then
- begin
- Result := WSAStartup($0101, wsaData) = 0;
- if not Result then
- Exit;
- end;
- Inc(FSockCount);
- Result := True;
- end;
- function TCnUDP.GetLocalHost: string;
- var
- p: PHostEnt;
- s: array[0..256] of AnsiChar;
- begin
- SockStartup;
- try
- GetHostName(@s, 256);
- p := GetHostByName(@s);
- Result := string(inet_ntoa(PInAddr(p^.h_addr_list^)^));
- finally
- SockCleanup;
- end;
- end;
- procedure TCnUDP.SetRecvBufSize(const Value: Cardinal);
- begin
- if FRecvBufSize <> Value then
- begin
- FRecvBufSize := Value;
- if FRecvBuf <> nil then
- begin
- // 释放,等待下次需要时重新分配
- FreeMem(FRecvBuf);
- FRecvBuf := nil;
- end;
- end;
- end;
- procedure TCnUDP.SetUDPRecvBufSize(const Value: Cardinal);
- var
- Data: DWORD;
- begin
- FUDPRecvBufSize := Value;
- if FListening then
- begin
- Data := FUDPRecvBufSize;
- WinSock.setsockopt(ThisSocket, SOL_SOCKET, SO_RCVBUF,
- PAnsiChar(@Data), SizeOf(Data));
- end;
- end;
- procedure TCnUDP.SetUDPSendBufSize(const Value: Cardinal);
- var
- Data: DWORD;
- begin
- FUDPSendBufSize := Value;
- if FListening then
- begin
- Data := FUDPSendBufSize;
- WinSock.setsockopt(ThisSocket, SOL_SOCKET, SO_SNDBUF,
- PAnsiChar(@Data), SizeOf(Data));
- end;
- end;
- end.
|