我可以使用IdUDPClient发送M-搜索请求?(Can I use IdUDPClient to

2019-06-25 06:04发布

有我的网络中少数的UPnP设备。 我想送M-SEARCH请求发送到网络,并希望从中得到了一些响应。 这就是我想:

var sIP, sOut: string;
    iPort: Word;
    S: TStringBuilder;
begin
  S := TStringBuilder.Create;
  try
    S.Append('M-SEARCH * HTTP/1.1').AppendLine
     .Append('HOST: 239.255.255.250:1900').AppendLine
     .Append('MAN: "ssdp:discover"').AppendLine
     .Append('MX: 10').AppendLine
     .Append('ST: ssdp:all').AppendLine;

    IdUDPClient1.ReceiveTimeout := 3000;
    IdUDPClient1.Broadcast(S.ToString, 1900, '239.255.255.250');
    sOut := IdUDPClient1.ReceiveString(sIP, iPort);
    Memo1.Lines.Add(sIP);
    Memo1.Lines.Add(IntToStr(iPort));
    Memo1.Lines.Add(sOut);
  finally
    S.Free;
  end;
end;

我收到UDP客户端什么都没有。 我使用Wireshark来监控网络流量,并没有消息是从我的主机发送出去。

有任何想法吗? 谢谢。

我找到了答案终于:

uses
  System.SysUtils, IdUDPClient, IdStack;

var S: TStringBuilder;
    U: TIdUDPClient;
    iPeerPort: Word;
    sPeerIP, sResponse: string;
begin
  U := TIdUDPClient.Create(nil);
  S := TStringBuilder.Create;
  try
    S.Append('M-SEARCH * HTTP/1.1').AppendLine
     .Append('HOST: 239.255.255.250:1900').AppendLine
     .Append('MAN: "ssdp:discover"').AppendLine
     .Append('MX: 3').AppendLine
     .Append('ST: ssdp:all').AppendLine
     .AppendLine;

    U.BoundIP := GStack.LocalAddress;
    U.Send('239.255.255.250', 1900, S.ToString);

    U.ReceiveTimeout := 1000;
    repeat
      sResponse := U.ReceiveString(sPeerIP, iPeerPort);
      if iPeerPort <> 0 then begin
        WriteLn(Format('%s:%d', [sPeerIP, iPeerPort]));
        WriteLn(sResponse);
      end;
    until iPeerPort = 0;
    ReadLn;
  finally
    S.Free;
    U.Free;
  end;
end.

Answer 1:

呼叫AppendLine()在字符串生成器的最后两次。 HTTP请求头是由两个CRLF双封端的,但仅追加一对,所以要发送一个不完整的请求。



Answer 2:

使用TIdUDPServer(印9)快速和肮脏的溶液。

在表单上放了TIdUDPServer组件,并使用对象检查组绑定到你的本地IP如。 10.1.0.78:0,BroadcastEnabled和活动设置为true。 放一个TMemo和TButton的形式。

完成的OnClick和UDPRead活动如下:

uses IdSocketHandle;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  IdUDPServer1.Send('239.255.255.250', 1900, 'M-SEARCH * HTTP/1.1' + #13#10 +
     'HOST: 239.255.255.250:1900' + #13#10 +
     'MAN: "ssdp:discover"'+ #13#10 +
     'MX: 3'+ #13#10 +
     'ST: ssdp:all'+ #13#10 +
     #13#10);
end;

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var 
   data: string;
begin

   setlength(data, Adata.Size - AData.Position); //No fragmentation :)        
   AData.ReadBuffer(data[1], length(data));

   memo1.Lines.Add('Read: ' + inttostr(AData.Position) + ' / ' + inttostr(AData.Size) + ' PeerIP: ' + ABinding.PeerIP);       
   memo1.Lines.Add(data);
end;

保存,运行和鲍勃是你的叔叔。



Answer 3:

对于多播M-SEARCH中,消息格式定义如下。 *之间的值为实际值的占位符。

M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: *seconds to delay response*
ST: *search target*
USER-AGENT: *OS/version UPnP/1.1 product/version*

所以,你需要修复ReceiveTimeout到

U.ReceiveTimeout := 3000;

它应该是至少等于在你的请求以延迟(MX:3)3秒= 3000毫秒



文章来源: Can I use IdUDPClient to send M-SEARCH request?
标签: delphi indy ssdp