網絡即時通訊問,請各位大蝦多多指點

rodyhd 2003-08-20 08:42:01
怎樣向局域網廣播消息,工作站接收後再做出一定的反應,采取哪種協議好些,TCP/IP, IPX...
...全文
38 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
hongqi162 2003-08-21
  • 打赏
  • 举报
回复
User Datagram Protocol (UDP)协议
chenbin 2003-08-21
  • 打赏
  • 举报
回复
一般是用UDP
IwantFlay 2003-08-21
  • 打赏
  • 举报
回复
udp
mj_hc 2003-08-21
  • 打赏
  • 举报
回复
广播还是用UDP好
给你一个例子:(转)
广播有两种,一种是directed broadcast:

比如你的网段是192.168.0.X
你就往192.168.0.255发就可以了

另一种是limited broadcast:

就是把UDP设成广播IP,一般是255.255.255.255
var
broadcast:bool;
broadcast:=true;
SetSockopt(FSocket,SOL_SOCKET,SO_BROADCAST, @broadcast,sizeof(broadcast));

两者都是可以的。
directed broadcast不需要SetSockopt(),以标准的C类网为例,直接发送x.x.x.255就可以了,
这种广播只有同一逻辑子网中的机器才能收到,也就是说对方地址应该是x.x.x.y,如果不是
即使在同一物理子网中也是收不到的。当然,这和子网掩码有关。

limited broadcast必须有SetSockopt(FSocket,SOL_SOCKET,SO_BROADCAST, @broadcast,sizeof(broadcast));
它的广播地址是255.255.255.255,它的好处是只要在同一子网中的主机,就可以收到这种
广播,而不必非要在统一逻辑子网中,例如,如果你的地址是x.x.x.1,那么这种广播,
地址是x.y.z.a的主机也能收到。

下面是用socket API实现limited broadcast的一个例子:
unit udp;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, winsock,
StdCtrls;

const
WM_SOCK = WM_USER + 1; //自定义windows消息
UDPPORT = 6543; //设定UDP端口号
//INADDR_ALLHOSTS_GROUP = u_long($e0000001); //D类地址224.0.0.1


(*
* Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP.
* Delphi5自带的winsock.pas中没有ip_mreq的定义。
*)

{type
ip_mreq = record
imr_multiaddr: in_addr; (* IP multicast address of group *)
imr_interface: in_addr; (* local IP address of interface *)
end;}

type
Tfrmmain = class(TForm)
Button1: TButton;
Edit1: TEdit;
Memo1: TMemo;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
s: TSocket;
addr: TSockAddr;
FSockAddrIn : TSockAddrIn;
//mreq:ip_mreq;
//利用消息实时获知UDP消息
procedure ReadData(var Message: TMessage); message WM_SOCK;
public
{ Public declarations }
procedure SendData(Content: String);
end;

var
frmmain: Tfrmmain;

implementation

{$R *.DFM}

procedure Tfrmmain.FormCreate(Sender: TObject);
var
TempWSAData: TWSAData;
optval: integer;
begin
// 初始化SOCKET
if WSAStartup($101, TempWSAData)=1 then
showmessage('StartUp Error!');

s := Socket(AF_INET, SOCK_DGRAM, 0);
if (s = INVALID_SOCKET) then //Socket创建失败
begin
showmessage(inttostr(WSAGetLastError())+' Socket创建失败');
CloseSocket(s);
//exit;
end;
//发送方SockAddr绑定
addr.sin_family := AF_INET;
addr.sin_addr.S_addr := INADDR_ANY;
addr.sin_port := htons(UDPPORT);
if Bind(s, addr, sizeof(addr)) <> 0 then
begin
showmessage('bind fail');
end;

optval:= 1;
if setsockopt(s,SOL_SOCKET,SO_BROADCAST,pchar(@optval),sizeof(optval)) = SOCKET_ERROR then
begin
showmessage('无法进行UDP广播');
end;

{mreq.imr_multiaddr.S_addr := INADDR_ALLHOSTS_GROUP;
mreq.imr_interface.S_addr := INADDR_ANY;
if setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,pchar(@mreq),sizeof(mreq)) = SOCKET_ERROR then
begin
showmessage('无法进行UDP组播');
end;}


WSAAsyncSelect(s, frmmain.Handle , WM_SOCK, FD_READ);
//接收端SockAddrIn设定
FSockAddrIn.SIn_Family := AF_INET;
FSockAddrIn.SIn_Port := htons(UDPPORT);

label3.Caption := '端口:'+inttostr(UDPPORT);
end;

procedure Tfrmmain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseSocket(s);
end;

procedure Tfrmmain.ReadData(var Message: TMessage);
var
buffer: Array [1..4096] of char;
len: integer;
flen: integer;
Event: word;
value: string;
begin
flen:=sizeof(FSockAddrIn);
FSockAddrIn.SIn_Port := htons(UDPPORT);
Event := WSAGetSelectEvent(Message.LParam);
if Event = FD_READ then
begin
len := recvfrom(s, buffer, sizeof(buffer), 0, FSockAddrIn, flen);
value := copy(buffer, 1, len);
Memo1.Lines.add(value)
end;
end;

procedure Tfrmmain.SendData(Content: String);
var
value{,hostname}: string;
len: integer;
begin
FSockAddrIn.SIn_Addr.S_addr := INADDR_BROADCAST;
//FSockAddrIn.SIn_Addr.S_addr := inet_addr(pchar(Edit1.text)); //INADDR_BROADCAST; //INADDR_BROADCAST = -1 ?
value := Content;
len := sendto(s, value[1], Length(value), 0, FSockAddrIn, sizeof(FSockAddrIn));
if (WSAGetLastError() <> WSAEWOULDBLOCK) and (WSAGetLastError() <> 0) then
showmessage(inttostr(WSAGetLastError()));
if len = SOCKET_ERROR then
showmessage('send fail');
if len <> Length(value) then
showmessage('Not Send all');
end;

procedure Tfrmmain.Button1Click(Sender: TObject);
begin
senddata(Edit2.text);
end;

end.
jpyc 2003-08-21
  • 打赏
  • 举报
回复
TCP/IP

http://218.56.11.178:8020/web/index.aspx

->下载基地->例程-网络技术->演示TCP通讯服务/客户的连接
rodyhd 2003-08-20
  • 打赏
  • 举报
回复
各位大哥,能否給個實例
draking 2003-08-20
  • 打赏
  • 举报
回复
广播最好用UDP,连接快,是TCP/IP协议族的一种
jackie168 2003-08-20
  • 打赏
  • 举报
回复
局域網用UDP。。。。(建議)
yckxzjj 2003-08-20
  • 打赏
  • 举报
回复
我用过UDP!

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧