在Delphi中,该怎样进行UDP广播啦??谢谢

解决方案 »

  1.   

    没试过: 
    TCP/IP是这样规定的:
    要实现广播,就要把目的地的IP地址全部置1. 
    例如你的IP是:  192.168.0.1
    要向内部广播, 目的地址就是 192.168.255.255
    试试看.
      

  2.   

    向内部广播, 目的地址就是 192.168.111.255
    UDP控件向所有的192.168.111段广播
      

  3.   

    Wnyu(创业 -- 第一个目标是开一家软件公司)  的方法不错,感觉可以我也没试过,凑热闹来了:)
      

  4.   

    广播有两种,一种是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;interfaceuses
      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.