摘自:http://moosewoler.blog.163.com/blog/static/6986605200801241719611/
作者:Moose W. Oler
1. 通过参考VC++的范例程序得知,UDP通信时,server端要做的工作有:open->bind->send/recv->close,其中bind这步很重要,它将一个socket绑定到一个本地地址。
2. TUDPServer是继承于TCustomIPClient的。缺少bind这一步过程,被设计为只能当作一个客户端来用。
3. 通过观察发现,TIPSocket实现了bind的封装,并且它的open方法继承于TBaseSocket——只完成了socket的创建,这恰恰是我们所需要的。我们只需要手动bind这个socket即可。
源码:
{server端设置}
program UDPServer;
{$APPTYPE CONSOLE}
uses
SysUtils,
Sockets,
WinSock;
const
DefaultPort='827';
var
aUDPServer : TIPSocket;
addr : TSockAddr;
rv,i : integer;
quit : boolean;
buf : array [0..255] of byte;
begin
{ TODO -oUser -cConsole Main : Insert code here }
quit:=false;
aUDPServer:=TIPSocket.Create(nil);
aUDPServer.LocalHost:=aUDPServer.LocalHostName;
aUDPServer.LocalPort:=DefaultPort;
aUDPServer.Protocol:=IPPROTO_UDP;
aUDPServer.SockType:=stDgram;
//在通常的Win32应用程序的主线程中使用时需要非阻塞模式,否则会引起程序挂起
//池龙补充
//aUDPServer.BlockMode:=bmNonBlocking;
aUDPServer.Active:=true;
addr:=aUDPServer.GetSocketAddr(aUDPServer.LocalHost,aUDPServer.LocalPort);
bind(aUDPServer.Handle,addr,sizeof(addr));
while not quit do
begin
fillchar(buf,255,0);
rv:=aUDPServer.Receivebuf(buf,sizeof(buf));
if rv<>Socket_Error then
begin
for i:=0 to rv do write(inttohex(buf[i],2),' ');
writeln;
for i:=0 to rv do write(chr(buf[i]));
writeln;
end;
end;
if assigned(aUDPServer) then
aUDPServer.Free;
end.
{client端}
unit UUDPClient;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Sockets;
type
TForm1 = class(TForm)
UdpSocket1: TUdpSocket;
Button1: TButton;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
DefaultPort = '827';
procedure TForm1.FormCreate(Sender: TObject);
begin
with UdpSocket1 do
begin
RemoteHost:='121.195.43.77';
RemotePort:=DefaultPort;
Active:=true;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
buf : array [1..256] of byte;
i:integer;
begin
fillchar(buf,length(buf),0);
if length(edit1.Text)then
begin
for i:=1 to length(edit1.Text) do buf[i]:=byte(edit1.Text[i]);
UDPSocket1.SendBuf(buf,length(edit1.Text));
end;
end;
end.