2012-06-06 11 views
5

Ci sono pochi dispositivi uPNP nella mia rete. Sto cercando di inviare la richiesta M-SEARCH alla rete e spero di ricevere alcune risposte da esso. Questo è quello che sto provando:Posso utilizzare IdUDPClient per inviare la richiesta 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; 

Non ricevo nulla dal client UDP. Uso Wireshark per monitorare il traffico di rete e nessun messaggio è stato inviato dal mio host.

Qualche idea? Grazie.

ho trovato la risposta infine:

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. 

risposta

6

chiamata AppendLine() due volte alla fine della stringa builder. Le intestazioni delle richieste HTTP sono terminate da due coppie CRLF, ma si sta aggiungendo solo una coppia, quindi si invia una richiesta incompleta.

+0

aggiungo un nuovo AppendLine() all'oggetto stringbuilder, ma non ho ricevuto alcuna risposta. Inoltre, non ho notato la richiesta inviata dal mio ospite durante il monitoraggio del traffico tramite WireShark. –

+0

Sei sicuro che '239.255.255.250' è l'IP di trasmissione corretto per la tua LAN? Quale IP e sottorete locale sono assegnati al PC del tuo cliente? –

+0

Se trasmetto a 239.255.255.255, posso vedere il traffico inviato dal mio host. Trasmesso a 239.255.255.250, non è stato rilevato alcun traffico. –

3

Soluzione rapida e sporca che utilizza TIdUDPServer (Indy 9).

Rilasciare il componente TIdUDPServer nel modulo e utilizzare Impostazioni oggetto Impostazioni tramite l'IP locale es. 10.1.0.78:0, impostare BroadcastEnabled e Active su true. Rilasciare un TMemo e un TButton nel modulo.

Completare i OnClick e UDPRead eventi come segue:

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; 

Salva, Esegui e Bob di tuo zio.

0

Per M-SEARCH multicast, il formato del messaggio è definito di seguito. I valori tra * * sono segnaposto per valori reali.

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* 

Quindi è necessario per risolvere ReceiveTimeout a

U.ReceiveTimeout := 3000; 

Dovrebbe essere almeno pari al ritardo nella richiesta (MX: 3) 3 sec = 3000 millisecondi

Problemi correlati