如题.  小弟这样处理效果很不理想, 不使用UDP控件(打包麻烦)如何广播传输?  ServerSocket1.Socket.Lock;
  ConnectCount:= ServerSocket1.Socket.ActiveConnections;
  for i:=0 to  ConnectCount-1 do  ServerSocket1.Socket.Connections[i].SendText('...');
  ServerSocket1.Socket.Unlock; 
  

解决方案 »

  1.   

    不能用这两个控件。可以用TNMUDP控件。
      

  2.   

    可以用TNMUDP控件
          indy控件也可以
          要不就用win socket 自己写
      

  3.   

    请问楼上二位, TNMUDP 控件中发送内容存在:后发先至或超过1024 丢包的问题吗?
      

  4.   

    UDP 是不是啊? 用SOCKET 可以吗?
    我用过UDP 比较麻烦, 懒得改了.
      

  5.   

    用Indy控件,一般的处理起来比较方便
      

  6.   

    广播实际是一种发往广播地址的UDP包,组播是发往组播地址的UDP包。
      

  7.   

    TCP协议是不能广播的,UDP或IPX才行看下面示例,是用SocketAPI写的:
    uses
      Windows, Winsock, Messages, SysUtils, Variants, Classes, Graphics, Controls,
      Forms,
      Dialogs, StdCtrls;const
      WM_SOCK = WM_USER + 1; //自定义windows消息
      UDPPORT = 6543; //设定UDP端口号
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Edit1: TEdit;
        GroupBox1: TGroupBox;
        Label2: TLabel;
        Label3: TLabel;
        CheckBox1: TCheckBox;
        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
      Form1: TForm1;implementation{$R *.dfm}{ TForm1 }function LocalIP: string;
    type
      TaPInAddr = array[0..10] of PInAddr;
      PaPInAddr = ^TaPInAddr;
    var
      phe: PHostEnt;
      pptr: PaPInAddr;
      Buffer: array[0..63] of char;
      I: Integer;
      GInitData: TWSADATA;begin
      WSAStartup($101, GInitData);
      Result := '';
      GetHostName(Buffer, SizeOf(Buffer));
      phe := GetHostByName(buffer);
      if phe = nil then
        Exit;
      pptr := PaPInAddr(Phe^.h_addr_list);
      I := 0;
      while pptr^[I] <> nil do
      begin
        result := StrPas(inet_ntoa(pptr^[I]^));
        Inc(I);
      end;
      WSACleanup;
    end;procedure TForm1.ReadData(var Message: TMessage);
    var
      buffer: array[1..4096] of char;
      len: integer;
      flen: integer;
      Event: word;
      value: string;
      ResultInf: TStringList;
    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);    if value = 'Server' then
          if CheckBox1.Checked then //如果当前是服务器,则返回确认消息
          begin
            try
              ResultInf := TStringList.Create;
              ResultInf.Values['IP'] := LocalIP;
              ResultInf.Values['Port'] := '123';
              senddata(ResultInf.CommaText);
            finally
              ResultInf.Free;
            end;
          end;
      end;
    end;procedure TForm1.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 TForm1.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, Handle, WM_SOCK, FD_READ);
      //接收端SockAddrIn设定
      FSockAddrIn.SIn_Family := AF_INET;
      FSockAddrIn.SIn_Port := htons(UDPPORT);  label3.Caption := '端口:' + inttostr(UDPPORT);end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      CloseSocket(s);end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      senddata(Edit1.text);end;end.
      

  8.   

    感谢xzhifei兄, 通过Socket API 以广播方式发送要重组包的大小吗? 包的大小的限制吗? 存在后发先至的问题吗? 有RTP/RTCP 的开发资料吗?
    多谢了!
      

  9.   

    帮忙UP,
    另,局域网中后发先至可以忽略!(个人观点)
    用BufferUdp可以实现广播和组播