2012-06-06 24 views
5

Có vài thiết bị uPNP trong mạng của tôi. Tôi đang cố gửi yêu cầu M-SEARCH tới mạng và hy vọng nhận được một số phản hồi từ mạng đó. Đây là những gì tôi đang cố gắng:Tôi có thể sử dụng IdUDPClient để gửi yêu cầu M-SEARCH không?

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; 

Tôi không nhận được gì từ ứng dụng khách UDP. Tôi sử dụng Wireshark để theo dõi lưu lượng mạng và không có tin nhắn nào được gửi từ máy chủ của tôi.

Bất kỳ ý tưởng nào? Cảm ơn bạn.

Tôi tìm thấy câu trả lời cuối cùng:

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. 

Trả lời

6

Gọi AppendLine() hai lần vào cuối của người xây dựng chuỗi. Các tiêu đề yêu cầu HTTP được chấm dứt bởi hai cặp CRLF, nhưng bạn chỉ thêm một cặp, vì vậy bạn đang gửi một yêu cầu không đầy đủ.

+0

tôi thêm một AppendLine mới() đối tượng stringbuilder, nhưng tôi cũng không nhận được bất kỳ phản hồi nào. Tôi cũng không nhận thấy yêu cầu gửi từ máy chủ của tôi khi theo dõi lưu lượng truy cập qua WireShark. –

+0

Bạn có chắc chắn rằng '239.255.255.250' là IP phát sóng chính xác cho mạng LAN của bạn không? IP địa phương và subnet nào được gán cho PC của khách hàng của bạn? –

+0

Nếu tôi phát sóng tới 239.255.255.255, tôi có thể thấy lưu lượng truy cập được gửi từ máy chủ của tôi. Nhưng phát sóng tới 239.255.255.250, không phát hiện thấy lưu lượng truy cập nào. –

3

Giải pháp Nhanh và Bẩn bằng TIdUDPServer (Indy 9).

Thả thành phần TIdUDPServer vào biểu mẫu và sử dụng bộ Ràng buộc đối tượng bộ kiểm tra đối với IP cục bộ của bạn, ví dụ: 10.1.0.78:0, đặt BroadcastEnabled và Active thành true. Thả một TMemo và TButton vào biểu mẫu.

Hoàn thành OnClick và UDPRead sự kiện như sau:

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; 

Lưu, Run và Bob chú của bạn.

0

Đối với M-SEARCH đa hướng, định dạng thông báo được xác định bên dưới. Giá trị giữa * * là phần giữ chỗ cho giá trị thực.

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* 

Vì vậy, bạn cần phải sửa chữa ReceiveTimeout để

U.ReceiveTimeout := 3000; 

Nó nên có ít nhất tương đương với sự chậm trễ trong yêu cầu của bạn (MX: 3) 3 giây = 3000 mili giây

Các vấn đề liên quan