2009-07-08 13 views
11

मुझे विशिष्ट आईपी और पोर्ट को यूडीपी संदेश भेजने की आवश्यकता है।सभी उपलब्ध नेटवर्क कार्डों को यूडीपी संदेश प्रसारित करना

के बाद से वहाँ 3 नेटवर्क कार्ड,

10.1.x.x 
10.2.x.x 
10.4.x.x 

जब मैं एक यूडीपी संदेश भेजते हैं, मैं केवल एक नेटवर्क एडाप्टर में संदेश प्राप्त कर रहा है ... आईपी के के बाकी नहीं ले पा रहे।

संदेश भेजने के दौरान मैं नेटवर्क एडाप्टर की जांच करना चाहता हूं। मैं उसे कैसे कर सकता हूँ?


वर्तमान में मैं निम्नलिखित का उपयोग कर रहा:

IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIP), 0); 
IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort); 
UdpClient sendUdpClient = new UdpClient(localEndPoint); 
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint); 
+0

आप और अधिक स्पष्ट कर सकते हैं कि आप क्या करते हैं की कोशिश कर चाहते हैं। –

+0

मेरा आवेदन 10+ सिस्टम में किसी एप्लिकेशन को संदेश भेजेगा। जिसमें सभी सिस्टम तीन अलग-अलग नेटवर्क कार्ड में हैं। 10.1.x.x/10.2.x.x/10.4.x.x की तरह मैं केवल एक नेटवर्क कार्ड 10.1.x.x में संदेश प्राप्त करने में सक्षम हूं लेकिन अन्य दो नेटवर्क कार्डों में नहीं। तो मैं नेटवर्क कार्ड की उपलब्धि की जांच करना चाहता हूं और फिर संदेश भेजना चाहता हूं। धन्यवाद। – Anuya

+0

क्या संदेश सिर्फ नेटवर्क उपलब्धता की जांच करने के लिए है, या क्या उसके पास कुछ अन्य पेलोड/अर्थ है? –

उत्तर

16

यह वास्तव में यह लगता है कि यह एक से अधिक इंटरफ़ेस है, तो प्रसारण वास्तव में सभी इंटरफ़ेस पर नहीं जाएंगे। इस के आसपास पाने के लिए मैंने इस वर्ग को बनाया।

public class MyUdpClient : UdpClient 
{ 
    public MyUdpClient() : base() 
    { 
     //Calls the protected Client property belonging to the UdpClient base class. 
     Socket s = this.Client; 
     //Uses the Socket returned by Client to set an option that is not available using UdpClient. 
     s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); 
     s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1); 
    } 

    public MyUdpClient(IPEndPoint ipLocalEndPoint) : base(ipLocalEndPoint) 
    { 
     //Calls the protected Client property belonging to the UdpClient base class. 
     Socket s = this.Client; 
     //Uses the Socket returned by Client to set an option that is not available using UdpClient. 
     s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); 
     s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1); 
    } 

} 

फिर प्रसारण के माध्यम से यूडीपी पैकेट भेजने के लिए, मैं निम्नलिखित की तरह कुछ उपयोग करता हूं। मैं IPAddress.Broadcast और MyUdpClient का उपयोग कर रहा हूं, जो आपके कोड से अलग है।

IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIP), 0); 
IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Broadcast, iTargetPort); 
MyUdpClient sendUdpClient = new MyUdpClient(localEndPoint); 
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint); 

इसके अलावा, आप को ध्यान देना चाहिए कि जब आप प्रसारण के बजाय एक विशिष्ट ipaddress का उपयोग मार्ग तालिका केवल यह इंटरफ़ेस है कि पते से मेल खाता बाहर भेजता है।

तो आपके उदाहरण में, यूनिकास्ट का उपयोग किया जाता है। आपको उस स्थानीय इंटरफ़ेस के आईपी पर LocalIP सेट करने की आवश्यकता है, जिसे आप भेजना चाहते हैं। तीन इंटरफेस के साथ, आपके पास तीन स्थानीय आईपी होंगे और आपको उपयोग करने के लिए सही चुनना होगा।

IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIP), 0); 
IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort); 
MyUdpClient sendUdpClient = new MyUdpClient(localEndPoint); 
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint); 

क्योंकि मार्ग बंद है क्योंकि आप इसे सभी इंटरफेस पर देख सकते हैं लेकिन आपको यूनिकास्ट केस के लिए इसका परीक्षण करने की आवश्यकता होगी।

यदि आपको आईपी या पोर्ट भेजने की परवाह नहीं है तो आप निम्न कोड का उपयोग कर सकते हैं।

IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort); 
MyUdpClient sendUdpClient = new MyUdpClient(); 
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint); 

या प्रसारण

IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Broadcast, iTargetPort); 
MyUdpClient sendUdpClient = new MyUdpClient(); 
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint); 

IPAddress.Broadcast के साथ समस्या यह है कि वे किसी भी द्वार के माध्यम से मार्ग नहीं होगा है। इसके आस-पास पहुंचने के लिए आप IPAddresses की एक सूची बना सकते हैं और फिर लूप के माध्यम से भेज सकते हैं और भेज सकते हैं। चूंकि प्रेषण उन नेटवर्क समस्याओं के लिए असफल हो सकता है जिन्हें आप नियंत्रित नहीं कर सकते हैं, आपको एक कोशिश/पकड़ ब्लॉक भी होना चाहिए।

ArrayList ip_addr_acq = new ArrayList(); 

ip_addr_acq.Add(IPAddress.Parse("10.1.1.1")); // add to list of address to send to 

try 
{ 
    foreach (IPAddress curAdd in ip_addr_acq) 
    { 
     IPEndPoint targetEndPoint = new IPEndPoint(curAdd , iTargetPort); 
     MyUdpClient sendUdpClient = new MyUdpClient(); 
     int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint); 

     Thread.Sleep(40); //small delay between each message 
    } 
} 
catch 
{ 
// handle any exceptions 
} 

संपादित करें: एकाधिक इंटरफेस के साथ यूनिकास्ट और भी Problem Trying to unicast packets to available networks.

+0

हाय रेक्स लोगान, जब मैंने आपका कोड आजमाया, तो मुझे निम्न त्रुटि मिल रही है: एक सॉकेट ऑपरेशन को एक अप्राप्य मेजबान का प्रयास किया गया था। मैं यहां उलझन में हूं, उस आईपी के साथ नेटवर्क एडेप्टर मौजूद है। जब मैंने नीचे दी गई रेखा को डीबग किया ... int numBytesSent = sendUdpClient.Send (CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint); मैंने targetEndPoint = {10.4.1.2:1982} देखा। जब targetEndPoint {10.1.1.1:1982} है तो मुझे दूरस्थ मशीन में पैकेट प्राप्त हो रहा है। ? :( – Anuya

+0

अगर आप IPAddress.Broadcast लिए भेज क्या होता है आप सरलीकृत संस्करण मैं भी जोड़ा की कोशिश कर सकते –

+0

तुम भी s.SetSocketOption बाहर टिप्पणी की कोशिश कर सकते (SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);। कहते हैं या s.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1) क्या होता है –

1

आप एक विशिष्ट आईपी पते पर भेजी जा रही है तो आप unicasting कर रहे हैं, नहीं प्रसारण हैं।

+0

ओह हाँ यह सही है। लेकिन मैं सही भेजने से पहले नेटवर्क का चयन करता हूं? – Anuya

+1

आह आप एक स्थानीय नेटवर्क कार्ड को एक नेटवर्क नेटवर्क के साथ रिमोट होस्ट पर एक पैकेट भेजने की कोशिश कर रहे हैं? यदि आप प्रत्येक नेटवर्क कार्ड का परीक्षण करने का प्रयास करते हैं, तो उस संदेश पर एक संदेश भेजने के लिए एक होस्ट खोजें। ओएस को आपके लिए रूटिंग करने दें। –

+0

लेकिन ओएस हमेशा पहले नेटवर्क कार्ड पर जा रहा है 10.1.x.x – Anuya

0

रेक्स के जवाब का विस्तार करने के लिए परिवर्तन ऊपर देखें। यह आपको उन IP पतों को कड़ी कोड करने की अनुमति नहीं देता है जिन्हें आप प्रसारित करना चाहते हैं। सभी इंटरफेस के माध्यम से लूप, जांचता है कि वे ऊपर हैं, सुनिश्चित करें कि इसमें आईपीवी 4 जानकारी है, और एक आईपीवी 4 पता इसके साथ जुड़ा हुआ है। बस "डेटा" वेरिएबल को जो भी डेटा प्रसारित करना चाहते हैं, उसे बदलें और "लक्ष्य" पोर्ट जिसे आप चाहते हैं।छोटी कमी यह है कि यदि किसी इंटरफेस में इसके साथ जुड़े कई आईपी पते हैं, तो यह प्रत्येक पते से प्रसारित होगा। नोट: यह किसी भी वीपीएन एडाप्टर (नेटवर्क और शेयरिंग सेंटर/नेटवर्क कनेक्शन, विन 7+ सत्यापित के माध्यम से) के माध्यम से प्रसारण भेजने का प्रयास करेगा, और यदि आप प्रतिक्रिया प्राप्त करना चाहते हैं, तो आपको सभी क्लाइंट को सहेजना होगा। आपको द्वितीयक वर्ग की भी आवश्यकता नहीं होगी।

foreach(NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) { 
     if(ni.OperationalStatus == OperationalStatus.Up && ni.SupportsMulticast && ni.GetIPProperties().GetIPv4Properties() != null) { 
      int id = ni.GetIPProperties().GetIPv4Properties().Index; 
      if(NetworkInterface.LoopbackInterfaceIndex != id) { 
       foreach(UnicastIPAddressInformation uip in ni.GetIPProperties().UnicastAddresses) { 
        if(uip.Address.AddressFamily == AddressFamily.InterNetwork) { 
         IPEndPoint local = new IPEndPoint(uip.Address.Address, 0); 
         UdpClient udpc = new UdpClient(local); 
         udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); 
         udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1); 
         byte[] data = new byte[10]{1,2,3,4,5,6,7,8,9,10}; 
         IPEndPoint target = new IPEndPoint(IPAddress.Broadcast, 48888); 
         udpc.Send(data,data.Length, target); 
        } 
       } 
      } 
     } 
    } 
0

मैं प्रत्येक एडाप्टर से यूडीपी प्रसारण भेजने (बाँध का प्रयोग करके) इस समस्या का समाधान:

public static void SNCT_SendBroadcast(out List<MyDevice> DevicesList) 
{ 
DevicesList = new List<MyDevice>(); 
byte[] data = new byte[2]; //broadcast data 
data[0] = 0x0A; 
data[1] = 0x60; 

IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, 45000); //braodcast IP address, and corresponding port 

NetworkInterface[] nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(); //get all network interfaces of the computer 

foreach (NetworkInterface adapter in nics) 
{ 
// Only select interfaces that are Ethernet type and support IPv4 (important to minimize waiting time) 
if (adapter.NetworkInterfaceType != NetworkInterfaceType.Ethernet) { continue; } 
if (adapter.Supports(NetworkInterfaceComponent.IPv4) == false) { continue; } 
try 
{ 
    IPInterfaceProperties adapterProperties = adapter.GetIPProperties();  
    foreach (var ua in adapterProperties.UnicastAddresses) 
    { 
     if (ua.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) 
     { 
     //SEND BROADCAST IN THE ADAPTER 
      //1) Set the socket as UDP Client 
      Socket bcSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //broadcast socket 
      //2) Set socker options 
      bcSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); 
      bcSocket.ReceiveTimeout = 200; //receive timout 200ms 
      //3) Bind to the current selected adapter 
      IPEndPoint myLocalEndPoint = new IPEndPoint(ua.Address, 45000); 
      bcSocket.Bind(myLocalEndPoint); 
      //4) Send the broadcast data 
      bcSocket.SendTo(data, ip); 

     //RECEIVE BROADCAST IN THE ADAPTER 
      int BUFFER_SIZE_ANSWER = 1024; 
      byte[] bufferAnswer = new byte[BUFFER_SIZE_ANSWER]; 
      do 
      { 
       try 
       { 
        bcSocket.Receive(bufferAnswer); 
        DevicesList.Add(GetMyDevice(bufferAnswer)); //Corresponding functions to get the devices information. Depends on the application. 
       } 
       catch { break; } 

      } while (bcSocket.ReceiveTimeout != 0); //fixed receive timeout for each adapter that supports our broadcast 
      bcSocket.Close(); 
     } 
    } 
    } 
    catch { } 
} 
return; 
} 
संबंधित मुद्दे