Z
zw84611
Unregistered / Unconfirmed
GUEST, unregistred user!
{-------------------------------------------------------------------------------
用UDP实现Windows信使服务,不用API,直接用UDP实现net send的功能
对指定IP地址发送消息,支持广播
可自定义发送和接收的机器名(因此支持匿名发送)
可在win9x下发送
此程序参照了http://www.vckbase.com/document/viewdoc.asp?id=951
感谢原作者,Delphi版翻译:zw84611@sina.com
似乎只能在Win2k pro上能接收。Win2k Server的信使服务似乎使用的是TCP(139端口),请帮
我测试。
不得将本程序用于任何商业用途。
-------------------------------------------------------------------------------}
unit udp;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, winsock,
StdCtrls;
const
MSGER_PORT = 135;
type
TMainForm = class(TForm)
btnSend: TButton;
edtDestIP: TEdit; //目的IP地址
Label1: TLabel;
Label2: TLabel;
edtSrcName: TEdit; //源主机名,可随意填
edtDestName: TEdit; //目的主机名,可随意填
mmSendText: TMemo; //发送消息的内容
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnSendClick(Sender: TObject);
private
{ Private declarations }
s: TSocket;
SockAddr: TSockAddrIn;
public
{ Public declarations }
procedure SendData(Content: String);
end;
PWORD = ^WORD;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.FormCreate(Sender: TObject);
var
TempWSAData: TWSAData;
begin
if WSAStartup($101, TempWSAData)=1 then
begin
ShowMessage('StartUp Error!');
Exit;
end;
s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
showmessage(inttostr(WSAGetLastError())+' Socket创建失败');
CloseSocket(s);
Exit;
end;
SockAddr.SIn_Family := AF_INET;
SockAddr.SIn_Port := htons(MSGER_PORT);
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(s);
end;
procedure TMainForm.SendData(Content: String);
const
PacketHeader:array[0..79] of byte = (
$04,$00,$28,$00,
$10,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
$00,$00,$00,$00,$f8,$91,$7b,$5a,$00,$ff,$d0,$11,$a9,$b2,$00,$c0,
$4f,$b6,$e6,$fc,
$ff,$ff,$ff,$ff, // @40 : unique id over 16 bytes ?
$ff,$ff,$ff,$ff,
$ff,$ff,$ff,$ff,
$ff,$ff,$ff,$ff,
$00,$00,$00,$00,$01,$00,$00,$00,$00,$00,$00,$00,
$00,$00,$ff,$ff,$ff,$ff,
$ff,$ff,$ff,$ff, // @74 : fields length
$00,$00
);
var
len: integer;
Pkt: array[0..8191] of byte;
FieldHeader:array[0..11] of byte;
SrcName, DestName: string;
SrcLen, DestLen, MsgLen, FieldsSize, TimeField: DWORD;
Pos: DWORD;
begin
SrcName := edtSrcname.Text;
DestName := edtDestName.Text;
SrcLen := Length(SrcName) + 1;
DestLen := Length(Destname) + 1;
MsgLen := Length(Content) + 1;
Pos := 0;
ZeroMemory(@Pkt[0], 8192);
CopyMemory(@Pkt[0], @PacketHeader[0], 80);
Pos := Pos + 80;
ZeroMemory(@FieldHeader[0], 12);
PWORD(@FieldHeader[0])^ := SrcLen;
PWORD(@FieldHeader[8])^ := SrcLen;
CopyMemory(@Pkt[Pos], @FieldHeader[0], 12);
Pos := Pos + 12;
CopyMemory(@Pkt[Pos], PChar(SrcName), SrcLen);
Pos := Pos + ((((SrcLen - 1)shr 2) + 1)shl 2); // padded to a multiple of 4
ZeroMemory(@FieldHeader[0], 12);
PWORD(@FieldHeader[0])^ := DestLen;
PWORD(@FieldHeader[8])^ := DestLen;
CopyMemory(@Pkt[Pos], @FieldHeader[0], 12);
Pos := Pos + 12;
CopyMemory(@Pkt[Pos], PChar(DestName), DestLen);
Pos := Pos + ((((DestLen - 1)shr 2) + 1)shl 2); // padded to a multiple of 4
ZeroMemory(@FieldHeader[0], 12);
PWORD(@FieldHeader[0])^ := MsgLen;
PWORD(@FieldHeader[8])^ := MsgLen;
CopyMemory(@Pkt[Pos], @FieldHeader[0], 12);
Pos := Pos + 12;
CopyMemory(@Pkt[Pos], PChar(Content), MsgLen);
Pos := Pos + MsgLen;
TimeField := DWORD(DateTimeToTimeStamp(Time).Time);
FieldsSize := Pos - 80;
PWORD(@Pkt[40])^ := TimeField;
PWORD(@Pkt[74])^ := FieldsSize;
SockAddr.SIn_Addr.S_addr := inet_addr(pchar(edtDestIP.Text));
len := SendTo(s, Pkt[0], Pos, 0, SockAddr, sizeof(SockAddr));
if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then
ShowMessage(inttostr(WSAGetLastError()));
if len = SOCKET_ERROR then ShowMessage('send fail');
end;
procedure TMainForm.btnSendClick(Sender: TObject);
begin
SendData(mmSendText.text);
end;
end.
用UDP实现Windows信使服务,不用API,直接用UDP实现net send的功能
对指定IP地址发送消息,支持广播
可自定义发送和接收的机器名(因此支持匿名发送)
可在win9x下发送
此程序参照了http://www.vckbase.com/document/viewdoc.asp?id=951
感谢原作者,Delphi版翻译:zw84611@sina.com
似乎只能在Win2k pro上能接收。Win2k Server的信使服务似乎使用的是TCP(139端口),请帮
我测试。
不得将本程序用于任何商业用途。
-------------------------------------------------------------------------------}
unit udp;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, winsock,
StdCtrls;
const
MSGER_PORT = 135;
type
TMainForm = class(TForm)
btnSend: TButton;
edtDestIP: TEdit; //目的IP地址
Label1: TLabel;
Label2: TLabel;
edtSrcName: TEdit; //源主机名,可随意填
edtDestName: TEdit; //目的主机名,可随意填
mmSendText: TMemo; //发送消息的内容
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnSendClick(Sender: TObject);
private
{ Private declarations }
s: TSocket;
SockAddr: TSockAddrIn;
public
{ Public declarations }
procedure SendData(Content: String);
end;
PWORD = ^WORD;
var
MainForm: TMainForm;
implementation
{$R *.DFM}
procedure TMainForm.FormCreate(Sender: TObject);
var
TempWSAData: TWSAData;
begin
if WSAStartup($101, TempWSAData)=1 then
begin
ShowMessage('StartUp Error!');
Exit;
end;
s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
showmessage(inttostr(WSAGetLastError())+' Socket创建失败');
CloseSocket(s);
Exit;
end;
SockAddr.SIn_Family := AF_INET;
SockAddr.SIn_Port := htons(MSGER_PORT);
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(s);
end;
procedure TMainForm.SendData(Content: String);
const
PacketHeader:array[0..79] of byte = (
$04,$00,$28,$00,
$10,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,
$00,$00,$00,$00,$f8,$91,$7b,$5a,$00,$ff,$d0,$11,$a9,$b2,$00,$c0,
$4f,$b6,$e6,$fc,
$ff,$ff,$ff,$ff, // @40 : unique id over 16 bytes ?
$ff,$ff,$ff,$ff,
$ff,$ff,$ff,$ff,
$ff,$ff,$ff,$ff,
$00,$00,$00,$00,$01,$00,$00,$00,$00,$00,$00,$00,
$00,$00,$ff,$ff,$ff,$ff,
$ff,$ff,$ff,$ff, // @74 : fields length
$00,$00
);
var
len: integer;
Pkt: array[0..8191] of byte;
FieldHeader:array[0..11] of byte;
SrcName, DestName: string;
SrcLen, DestLen, MsgLen, FieldsSize, TimeField: DWORD;
Pos: DWORD;
begin
SrcName := edtSrcname.Text;
DestName := edtDestName.Text;
SrcLen := Length(SrcName) + 1;
DestLen := Length(Destname) + 1;
MsgLen := Length(Content) + 1;
Pos := 0;
ZeroMemory(@Pkt[0], 8192);
CopyMemory(@Pkt[0], @PacketHeader[0], 80);
Pos := Pos + 80;
ZeroMemory(@FieldHeader[0], 12);
PWORD(@FieldHeader[0])^ := SrcLen;
PWORD(@FieldHeader[8])^ := SrcLen;
CopyMemory(@Pkt[Pos], @FieldHeader[0], 12);
Pos := Pos + 12;
CopyMemory(@Pkt[Pos], PChar(SrcName), SrcLen);
Pos := Pos + ((((SrcLen - 1)shr 2) + 1)shl 2); // padded to a multiple of 4
ZeroMemory(@FieldHeader[0], 12);
PWORD(@FieldHeader[0])^ := DestLen;
PWORD(@FieldHeader[8])^ := DestLen;
CopyMemory(@Pkt[Pos], @FieldHeader[0], 12);
Pos := Pos + 12;
CopyMemory(@Pkt[Pos], PChar(DestName), DestLen);
Pos := Pos + ((((DestLen - 1)shr 2) + 1)shl 2); // padded to a multiple of 4
ZeroMemory(@FieldHeader[0], 12);
PWORD(@FieldHeader[0])^ := MsgLen;
PWORD(@FieldHeader[8])^ := MsgLen;
CopyMemory(@Pkt[Pos], @FieldHeader[0], 12);
Pos := Pos + 12;
CopyMemory(@Pkt[Pos], PChar(Content), MsgLen);
Pos := Pos + MsgLen;
TimeField := DWORD(DateTimeToTimeStamp(Time).Time);
FieldsSize := Pos - 80;
PWORD(@Pkt[40])^ := TimeField;
PWORD(@Pkt[74])^ := FieldsSize;
SockAddr.SIn_Addr.S_addr := inet_addr(pchar(edtDestIP.Text));
len := SendTo(s, Pkt[0], Pos, 0, SockAddr, sizeof(SockAddr));
if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then
ShowMessage(inttostr(WSAGetLastError()));
if len = SOCKET_ERROR then ShowMessage('send fail');
end;
procedure TMainForm.btnSendClick(Sender: TObject);
begin
SendData(mmSendText.text);
end;
end.