A类互联网网址: 7位网络号 24位主机号
01111111.11111111.11111111.11111111 --->01111111 = 127
0..127 0..255 0..255 0..255
0.0.0.0 -- 127.255.255.255
B类互联网网址: 14位网络号 16位主机号
10111111.11111111.11111111.11111111 --->10111111 = 191
128..191 0..255 0..255 0..255
128.0.0.0 -- 191.255.255.255
C类互联网网址: 21位网络号 8位主机号
11011111.11111111.11111111.11111111 --->11011111 = 223
192..223 0..255 0..255 0..255
192.0.0.0 -- 223.255.255.255
多播地址: 224.0.0.0 -- 255.255.255.255
Winsock1 IP/UDP多播的小实验:
const
MCASTADDR = '234.5.6.7';
MCASTPORT = 25000;
LOCAL_PORT = 5555;
WM_SOCKET = WM_USER + 55;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
ListBox1: TListBox;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
procedure WMSocket(var Msg: TMessage); message WM_SOCKET;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure ErrMsg( msg: string );
begin
MessageBox( 0, PChar(msg), 'Ping Program Error', MB_ICONERROR );
end;
procedure TForm1.WMSocket(var Msg: TMessage);
var
buf:array[0..255]of char;
remote:TSockaddr;
len:integer; p:string;
begin
case WSAGetSelectEvent( Msg.LParam ) of
FD_READ :
begin
recvfrom(msg.WParam, buf[0], 255,0, remote, len );
getpeername( msg.WParam, remote, len );
p := inet_ntoa(remote.sin_addr) + ' Port: ' + inttostr(ntohs(remote.sin_port));
listbox1.Items.Add(p + buf);
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
wsa : TWSAData;
begin
if WSAStartup( $0202, wsa ) <> 0 then
ErrMsg( 'Windows socket is not responed.' );
listbox1.Font.Name := 'Courier New';
listbox1.Font.Size := 9;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if WSACleanup <> 0 then
ErrMsg( 'Windows socket can not be closed.' );
end;
procedure TForm1.Button1Click(Sender: TObject);
var
sock : TSocket;
local,
remote : TSockAddr;
bufsend : Array[0..31]of char;
ret,i : s32;
ttl, opt : s32;
bSender :bool;
mcast :ip_mreq;
begin
bSender := CheckBox1.Checked;
sock := socket( AF_INET, SOCK_DGRAM, 0 );
if sock = INVALID_SOCKET then
begin
ErrMsg( 'socket Failed: ' + IntToStr(WSAGetLastError) );
exit;
end;
local.sin_family := AF_INET;
local.sin_port := htons(u16(MCASTPort));
local.sin_addr.S_addr := inet_addr('192.168.1.12');
//
if bind( sock, @local, SizeOf(local) )= SOCKET_ERROR then
begin
ErrMsg( 'bind Failed: ' + IntToStr(WSAGetLastError) );
closesocket(sock);
exit;
end;
if WSAAsyncSelect( sock, Handle, WM_SOCKET, FD_READ ) = socket_error then
begin
ErrMsg( 'WSAAsyncSelect Failed: ' + IntToStr(WSAGetLastError) );
closesocket(sock);
exit;
end;
remote.sin_family := AF_INET;
remote.sin_port := htons( MCASTPort );
remote.sin_addr.S_addr := inet_addr(MCASTADDR);
mcast.imr_multiaddr.S_addr := remote.sin_addr.S_addr;
mcast.imr_interface.S_addr := local.sin_addr.S_addr;
if setsockopt( sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, @mcast, sizeof(mcast) )=SOCKET_ERROR then
begin
ErrMsg( 'setsockopt Failed: ' + IntToStr(WSAGetLastError) );
closesocket(sock);
exit;
end;
Opt := 8;
if setsockopt( sock, IPPROTO_IP, IP_MULTICAST_TTL, @opt, sizeof(opt) )=SOCKET_ERROR then
begin
ErrMsg( 'setsockopt Failed: ' + IntToStr(WSAGetLastError) );
closesocket(sock);
exit;
end;
//要发送的UDP数据
FillChar( bufSend, 32, 'C' );
if bSender then for i:=0 to 3 do
begin
ret :=sendto( sock, bufsend[0], 32, 0, remote, sizeof(remote));
if ret =socket_error then
begin
ErrMsg( 'sendto Failed: ' + IntToStr(WSAGetLastError) );
//closesocket(sock);
break;
end;
end;
//closesocket( sock );
// closesocket(sockm);
end;
本来还想试验一下Winsock2多播的,可是发现多播并不支持广域网,没有兴趣了~~~