2012-06-06 10 views
5

Hay pocos dispositivos uPNP en mi red. Estoy tratando de enviar la solicitud M-SEARCH a la red y espero recibir algunas respuestas de la misma. Esto es lo que estoy tratando:¿Puedo usar IdUDPClient para enviar la solicitud 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; 

recibo nada desde el cliente UDP. Uso Wireshark para supervisar el tráfico de red y no se envió ningún mensaje desde mi host.

¿Alguna idea? Gracias.

he encontrado la respuesta por último:

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. 

Respuesta

6

llamada AppendLine() dos veces al final del constructor de cadena. Los encabezados de solicitud HTTP son cancelados por dos pares CRLF, pero usted solo está agregando un par, por lo que está enviando una solicitud incompleta.

+0

agrego un nuevo AppendLine() al objeto del generador de cadenas, pero tampoco recibí ninguna respuesta. Tampoco noté la solicitud enviada por mi anfitrión cuando superviso el tráfico a través de WireShark. –

+0

¿Está seguro de que '239.255.255.250' es la IP de transmisión correcta para su LAN? ¿Qué IP y subred locales se asignan a la PC de su cliente? –

+0

Si transmito a 239.255.255.255, puedo ver el tráfico enviado desde mi host. Pero se transmitió a 239.255.255.250, no se detectó tráfico. –

3

Solución rápida y sucia utilizando TIdUDPServer (Indy 9).

Coloque el componente TIdUDPServer en el formulario y, utilizando el Inspector de objetos, establezca Vinculaciones en su IP local, por ejemplo. 10.1.0.78:0, establece BroadcastEnabled y Active en verdadero. Coloque un TMemo y TButton en el formulario.

Complete los eventos OnClick y UDPRead de la siguiente manera:

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; 

Guardar, Ejecutar y Bob es tu tío.

0

Para multidifusión M-SEARCH, el formato del mensaje se define a continuación. Los valores entre * * son marcadores de posición para valores reales.

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* 

por lo que necesita para fijar ReceiveTimeout a

U.ReceiveTimeout := 3000; 

Debe ser por lo menos igual a la demora en su solicitud (MX: 3) 3 seg = 3000 milisegundos

Cuestiones relacionadas