总算知道怎样去实现了,其实只要知道双方上网的动态ip地址就好办了。怎样让客户端知
道服务端的ip那是另一回事。我把获取本机上网的动态ip地址贴出来,以谢大家的热心。
控件代码:
unit OnlineIP;
interface
uses
Windows, Messages, Winsock, Classes, Forms;
type
TOnlineIP = class(TComponent)
private
FEnabled: Boolean;
FDispatchInterval: Cardinal;
FWindowHandle: hWnd;
FOnline: Boolean;
FIP: String;
FOnChanged: TNotifyEvent;
procedure UpdateTimer;
procedure SetEnabled(Value: Boolean);
procedure SetDispatchInterval(Value: Cardinal);
procedure SetNoneBool(Value: Boolean);
procedure SetNoneStr(Value: String);
procedure WndProc(var Msg: TMessage);
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled;
property DispatchInterval: Cardinal read FDispatchInterval write SetDispatchInterval;
property Online: Boolean read FOnline write SetNoneBool;
property IP: String read FIP write SetNoneStr;
property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
end;
procedure Register;
implementation
function LocalIP: String;
type
TaPInAddr = Array[0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe: PHostEnt;
pptr: PaPInAddr;
Buffer: Array[0..63] of Char;
I: Integer;
GInitData: TWSAData;
begin
WSAStartup($101, GInitData);
Result := '';
GetHostName(Buffer, SizeOf(Buffer));
phe := GetHostByName(buffer);
if phe = nil then Exit;
pPtr := PaPInAddr(phe^.h_addr_list);
I := 0;
while pPtr^ <> nil do
begin
Result := inet_ntoa(pptr^^);
Inc(I);
end;
WSACleanup;
end;
constructor TOnlineIP.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := True;
FDispatchInterval := 1000;
FWindowHandle := AllocateHWnd(WndProc);
UpdateTimer;
end;
destructor TOnlineIP.Destroy;
begin
FEnabled := False;
UpdateTimer;
DeallocateHWnd(FWindowHandle);
inherited Destroy;
end;
procedure TOnlineIP.WndProc(var Msg: TMessage);
var
OldState: Boolean;
begin
with Msg do
if Msg = wm_Timer then
try
FIP := LocalIP;
OldState := FOnline;
FOnline := (FIP <> '') and (FIP <> '127.0.0.1');
if (not OldState and FOnline) or
(OldState and not FOnline) then
if Assigned(FOnChanged) then FOnChanged(Self);
except
Application.HandleException(Self);
end
else
Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
end;
procedure TOnlineIP.UpdateTimer;
begin
KillTimer(FWindowHandle, 1);
if (FDispatchInterval <> 0) and FEnabled then
SetTimer(FWindowHandle, 1, FDispatchInterval, nil);
end;
procedure TOnlineIP.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
UpdateTimer;
end;
end;
procedure TOnlineIP.SetDispatchInterval(Value: Cardinal);
begin
if Value <> FDispatchInterval then
begin
FDispatchInterval := Value;
UpdateTimer;
end;
end;
procedure TOnlineIP.SetNoneBool(Value: Boolean); begin {} end;
procedure TOnlineIP.SetNoneStr(Value: String); begin {} end;
procedure Register;
begin
RegisterComponents('Xacker', [TOnlineIP]);
end;
end.
实例代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, OnlineIP;
type
TForm1 = class(TForm)
Label1: TLabel;
GroupBox1: TGroupBox;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
OnlineIP1: TOnlineIP;
procedure OnlineIP1Changed(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.OnlineIP1Changed(Sender: TObject);
begin
if OnlineIP1.Online then
begin
Label3.Font.Color := clGreen;
Label3.Caption := 'Online';
Label4.Caption := 'IP: ' + OnlineIP1.IP;
end
else
begin
Label3.Font.Color := clMaroon;
Label3.Caption := 'Offline';
Label4.Caption := '';
end;
end;
end.