2012-10-09 16 views
11

UPnPマルチキャスト(Windows 7 Professional 64 Bitで動作するVisual C#2010 Express)をテストするための小さなプログラムを作成しました。私のネットワーク上のUPnPデバイスからUPnP NOTIFYメッセージを受け取ることができます。しかし、私がM-SEARCHメッセージを送るとき、私は答えを得ません。UPnPマルチキャスト:M-SEARCH(ディスカバリー)の回答がありません

私はiOS環境(MacのiPhoneシミュレータで動作するiOS用Monotouch)で同じコードをテストしました。そこでは正常に動作し、私はUPnPデバイスからすべての検索応答を取得します。私はまた、私のWindowsプログラムからM-SEARCHメッセージを見ることができます。

Windows(またはFirewall?)が検索応答を隠しているようです。何か案が?ここで

コードです:

IPEndPoint LocalEndPoint = new IPEndPoint(IPAddress.Any, 1900); 
IPEndPoint MulticastEndPoint = new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900); 

Socket UdpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 

UdpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
UdpSocket.Bind(LocalEndPoint); 
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(MulticastEndPoint.Address, IPAddress.Any)); 
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2); 
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true); 

Console.WriteLine("UDP-Socket setup done...\r\n"); 

string SearchString = "M-SEARCH * HTTP/1.1\r\nHOST:239.255.255.250:1900\r\nMAN:\"ssdp:discover\"\r\nST:ssdp:all\r\nMX:3\r\n\r\n"; 

UdpSocket.SendTo(Encoding.UTF8.GetBytes(SearchString), SocketFlags.None, MulticastEndPoint); 

Console.WriteLine("M-Search sent...\r\n"); 

byte[] ReceiveBuffer = new byte[64000]; 

int ReceivedBytes = 0; 

while (true) 
{ 
    if (UdpSocket.Available > 0) 
    { 
     ReceivedBytes = UdpSocket.Receive(ReceiveBuffer, SocketFlags.None); 

     if (ReceivedBytes > 0) 
     { 
      Console.WriteLine(Encoding.UTF8.GetString(ReceiveBuffer, 0, ReceivedBytes)); 
     } 
    } 
} 
+0

MulticastEndPointは何に設定されていますか? – simonc

+0

iOSで表示されるM-SEARCHは、Windowsプログラムのものですか?あなたのWindowsボックスで別のUPnP発見ツールを試しましたか? –

+0

@PavelZdenek:はい私は確信しています。私はM-SEARCHメッセージにいくつかの余分な文字を添付して、iOS上のメッセージを認識することができました。 –

答えて

15

ええ、私はこの問題を解決しました!小さな間違い、大きな影響:

私のプログラムは、UPnPマルチキャストグループにバインドされているポート1900でM-SEARCHを送信しています。 LocalEndPointを同じポートにバインドしているため、UPnPデバイスはユニキャストでポート1900に応答します.iOSでは、このプログラムがこのポートにバインドされている唯一のサービスであったため、機能しました。しかし、PC上で、私は1900年に接続されたいくつかのサービスを見つけました( "netstat -p UDP -a"で見つかりました)。したがって、UPnPデバイスからのユニキャストメッセージは、他のサービスの1つによって吸収されました。

解決策:LocalEndPointを空きポート(60000など)にバインドしました。これで正常に動作します。

IPEndPoint LocalEndPoint = new IPEndPoint(IPAddress.Any, 60000); 
+1

あなたは私より速いです:-)うん、WindowsはデフォルトでSSDPサービスを実行します。 netstatオプションで見てください-b –

+0

私は同じ問題がありますが、私のポートを変更することはできません。この問題を解決する他の方法はありますか? – Kingpin

+3

特定のポート(60000)にバインドしないで、一時的な(0)を求めてください!それとも、誰かが60000を使用しているためにこれが失敗するかもしれない –

4

ローカルエンドポイントの作成時に、固定ポートを使用しない空きポートをバインドするためにポート0(ゼロ)を使用します。発見された別のポイント。 IPAddress.AnyまたはIPAddress.Loopbackをバインドすると、Microsoft(local?)システムからの応答が得られます。ここで、LANアドレスの1つにバインドすると、ローカルネットからの応答が得られます。最初のIPv4アドレスを取得すると、次のように行うことができます。後世のために

IPAddress localNetwork = Dns.GetHostAddresses(Environment.GetEnvironmentVariable("COMPUTERNAME")).Where(ia => (ia.AddressFamily == AddressFamily.InterNetwork)).First(); 
+0

実際にIPV4に境界はありません。私はIP V6マルチキャストアドレスFF02 :: C(リンクローカル)、FF05 :: C(サイトローカル) FF08 :: C(組織ローカル)およびFF0E :: C(グローバル)。 IP V4のスコープはサイトローカルであることに注意してください。 [Wikipedia - SSDP](https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol)にあります。 – VBWebProfi

+0

'' Environment.GetEnvironmentVariable( "COMPUTERNAME") ''は '' Environment.MachineName''で置き換えることができます。 – VBWebProfi

1

:上記のすべてのこれらのオプションを設定すると、M-SEARCHのために不必要であるとさえ逆効果かもしれません:だから

UdpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(MulticastEndPoint.Address, IPAddress.Any)); 
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 2); 
UdpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true); 

ありませんそれをやる。

関連する問題