📄 idudpbase.pas
字号:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence }
{ Team Coherence is Copyright 2002 by Quality Software Components }
{ }
{ For further information / comments, visit our WEB site at }
{ http://www.TeamCoherence.com }
{**********************************************************************}
{}
{ $Log: 10407: IdUDPBase.pas
{
{ Rev 1.0 2002.11.12 10:58:48 PM czhower
}
unit IdUDPBase;
interface
uses
Classes,
IdComponent, IdException, IdGlobal, IdSocketHandle;
const
ID_UDP_BUFFERSIZE = 8192;
type
TIdUDPBase = class(TIdComponent)
protected
FBinding: TIdSocketHandle;
FBufferSize: Integer;
FDsgnActive: Boolean;
FHost: String;
FPort: Integer;
FReceiveTimeout: Integer;
//
FBroadcastEnabled: Boolean;
procedure BroadcastEnabledChanged; dynamic;
procedure CloseBinding; virtual;
function GetActive: Boolean; virtual;
procedure SetActive(const Value: Boolean);
procedure SetBroadcastFlag(const Enabled: Boolean; ABinding: TIdSocketHandle = nil);
procedure SetBroadcastEnabled(const Value: Boolean);
function GetBinding: TIdSocketHandle; virtual;
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
//
property Binding: TIdSocketHandle read GetBinding;
procedure Broadcast(const AData: string; const APort: integer);
function ReceiveBuffer(var ABuffer; const ABufferSize: Integer;
const AMSec: Integer = IdTimeoutDefault): integer; overload;
function ReceiveBuffer(var ABuffer; const ABufferSize: Integer; var VPeerIP: string;
var VPeerPort: integer; AMSec: Integer = IdTimeoutDefault): integer; overload;
function ReceiveString(const AMSec: Integer = IdTimeoutDefault): string; overload;
function ReceiveString(var VPeerIP: string; var VPeerPort: integer;
const AMSec: Integer = IdTimeoutDefault): string; overload;
procedure Send(AHost: string; const APort: Integer; const AData: string);
procedure SendBuffer(AHost: string; const APort: Integer; var ABuffer;
const AByteCount: integer);
//
property ReceiveTimeout: Integer read FReceiveTimeout write FReceiveTimeout default IdTimeoutInfinite;
published
property Active: Boolean read GetActive write SetActive Default False;
property BufferSize: Integer read FBufferSize write FBufferSize default ID_UDP_BUFFERSIZE;
property BroadcastEnabled: Boolean read FBroadcastEnabled write SetBroadcastEnabled Default False;
end;
EIdUDPException = Class(EIdException);
EIdUDPReceiveErrorZeroBytes = class(EIdUDPException);
implementation
uses
IdResourceStrings, IdStack, IdStackConsts, SysUtils;
{ TIdUDPBase }
procedure TIdUDPBase.Broadcast(const AData: string; const APort: integer);
begin
SetBroadcastFlag(True);
Send('255.255.255.255', APort, AData); {Do not Localize}
BroadcastEnabledChanged;
end;
procedure TIdUDPBase.BroadcastEnabledChanged;
begin
SetBroadcastFlag(BroadcastEnabled);
end;
procedure TIdUDPBase.CloseBinding;
begin
FreeAndNil(FBinding);
end;
constructor TIdUDPBase.Create(AOwner: TComponent);
begin
inherited;
BufferSize := ID_UDP_BUFFERSIZE;
FReceiveTimeout := IdTimeoutInfinite;
end;
destructor TIdUDPBase.Destroy;
begin
Active := False;
inherited;
end;
function TIdUDPBase.GetActive: Boolean;
begin
Result := FDsgnActive or (Assigned(FBinding) and FBinding.HandleAllocated);
end;
function TIdUDPBase.GetBinding: TIdSocketHandle;
begin
if not Assigned(FBinding)then begin
FBinding := TIdSocketHandle.Create(nil);
end;
if not FBinding.HandleAllocated then begin
FBinding.AllocateSocket(Id_SOCK_DGRAM);
BroadcastEnabledChanged;
end;
result := FBinding;
end;
procedure TIdUDPBase.Loaded;
var
b: Boolean;
begin
inherited;
b := FDsgnActive;
FDsgnActive := False;
Active := b;
end;
function TIdUDPBase.ReceiveBuffer(var ABuffer; const ABufferSize: Integer;
const AMSec: Integer): Integer;
var
VoidIP: string;
VoidPort: Integer;
begin
Result := ReceiveBuffer(ABuffer, ABufferSize, VoidIP, VoidPort, AMSec);
end;
function TIdUDPBase.ReceiveBuffer(var ABuffer; const ABufferSize: Integer;
var VPeerIP: string; var VPeerPort: integer;
AMSec: Integer = IdTimeoutDefault): integer;
begin
if AMSec = IdTimeoutDefault then begin
AMSec := ReceiveTimeOut;
end;
if not Binding.Readable(AMSec) then begin
Result := 0;
VPeerIP := ''; {Do not Localize}
VPeerPort := 0;
Exit;
end;
Result := Binding.RecvFrom(ABuffer, ABufferSize, 0, VPeerIP, VPeerPort);
GStack.CheckForSocketError(Result);
end;
function TIdUDPBase.ReceiveString(var VPeerIP: string; var VPeerPort: integer;
const AMSec: Integer = IdTimeoutDefault): string;
var
i: integer;
begin
SetLength(Result, BufferSize);
i := ReceiveBuffer(Result[1], Length(Result), VPeerIP, VPeerPort, AMSec);
SetLength(Result, i);
end;
function TIdUDPBase.ReceiveString(const AMSec: Integer): string;
var
VoidIP: string;
VoidPort: Integer;
begin
result := ReceiveString(VoidIP, VoidPort, AMSec);
end;
procedure TIdUDPBase.Send(AHost: string; const APort: Integer; const AData: string);
begin
SendBuffer(AHost, APort, PChar(AData)^, Length(AData));
end;
procedure TIdUDPBase.SendBuffer(AHost: string; const APort: Integer; var ABuffer;
const AByteCount: integer);
begin
AHost := GStack.ResolveHost(AHost);
Binding.SendTo(AHost, APort, ABuffer, AByteCount);
end;
procedure TIdUDPBase.SetActive(const Value: Boolean);
begin
if (Active <> Value) then begin
if not ((csDesigning in ComponentState) or (csLoading in ComponentState)) then begin
if Value then begin
GetBinding;
end
else begin
CloseBinding;
end;
end
else begin // don't activate at designtime (or during loading of properties) {Do not Localize}
FDsgnActive := Value;
end;
end;
end;
procedure TIdUDPBase.SetBroadcastEnabled(const Value: Boolean);
begin
if FBroadCastEnabled <> Value then begin
FBroadcastEnabled := Value;
if Active then begin
BroadcastEnabledChanged;
end;
end;
end;
procedure TIdUDPBase.SetBroadcastFlag(const Enabled: Boolean; ABinding: TIdSocketHandle = nil);
var
BroadCastData: LongBool;
begin
BroadCastData := Enabled;
if ABinding = nil then begin
ABinding := Binding;
end;
ABinding.SetSockOpt(Id_SOL_SOCKET, Id_SO_BROADCAST, PChar(@BroadCastData), SizeOf(BroadCastData));
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -