c# - विंडोज फोन 8 पर यूडीपी मल्टीकास्ट समूह




sockets udp windows-phone-8 datagram (4)

क्या आपने कभी एक और मल्टीकास्ट समूह में शामिल होने का प्रयास किया है? क्योंकि 224.0.1.1 आईएएनए असाइनमेंट के रूप में उपयोग में प्रतीत होता है। आप here सब मिलते here

शायद विंडोज फोन 8 पर कुछ सेवा आने वाले संदेशों को सुनने के लिए कड़ी बाध्य है (उदाहरण के लिए कर्नेल मोड में चल रही एक नेटवर्क सेवा) और वे आपको कभी अग्रेषित नहीं की जाती हैं।

ठीक है यह एक है जिसे मैं कुछ दिनों के लिए पता लगाने की कोशिश कर रहा हूं। हमारे पास विंडोज फोन 7 पर एक एप्लीकेशन है जहां फोन मल्टीकास्ट समूह में शामिल होते हैं और फिर एक-दूसरे से बात करने के लिए समूह को संदेश भेजते और प्राप्त करते हैं। नोट - यह फोन संचार के लिए फोन है।

अब मैं इस एप्लिकेशन को विंडोज फोन 8 पर पोर्ट करने की कोशिश कर रहा हूं - विजुअल स्टूडियो 2012 में 'कन्वर्ट टू फोन 8' सुविधा का उपयोग करके - अब तक इतना अच्छा है। जब तक मैं फोन संचार के लिए फोन का परीक्षण करने की कोशिश नहीं करता। हैंडसेट समूह जुर्माना में शामिल होने लगते हैं, और वे डेटाग्राम ठीक भेजते हैं। वे समूह को भेजे गए संदेश भी प्राप्त करते हैं - हालांकि, किसी हैंडसेट को कभी भी किसी अन्य हैंडसेट से संदेश प्राप्त नहीं होता है।

मेरे पृष्ठ के पीछे नमूना कोड यहां दिया गया है:

// Constructor
public MainPage()
{
    InitializeComponent();
}

// The address of the multicast group to join.
// Must be in the range from 224.0.0.0 to 239.255.255.255
private const string GROUP_ADDRESS = "224.0.1.1";

// The port over which to communicate to the multicast group
private const int GROUP_PORT = 55562;

// A client receiver for multicast traffic from any source
UdpAnySourceMulticastClient _client = null;

// Buffer for incoming data
private byte[] _receiveBuffer;

// Maximum size of a message in this communication
private const int MAX_MESSAGE_SIZE = 512;

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    _client = new UdpAnySourceMulticastClient(IPAddress.Parse(GROUP_ADDRESS), GROUP_PORT);
    _receiveBuffer = new byte[MAX_MESSAGE_SIZE];

    _client.BeginJoinGroup(
        result =>
        {
            _client.EndJoinGroup(result);
            _client.MulticastLoopback = true;
            Receive();
        }, null);
}

private void SendRequest(string s)
{
    if (string.IsNullOrWhiteSpace(s)) return;

    byte[] requestData = Encoding.UTF8.GetBytes(s);

    _client.BeginSendToGroup(requestData, 0, requestData.Length,
        result =>
        {
            _client.EndSendToGroup(result);
            Receive();
        }, null);
}

private void Receive()
{
    Array.Clear(_receiveBuffer, 0, _receiveBuffer.Length);
    _client.BeginReceiveFromGroup(_receiveBuffer, 0, _receiveBuffer.Length,
        result =>
        {
            IPEndPoint source;

            _client.EndReceiveFromGroup(result, out source);

            string dataReceived = Encoding.UTF8.GetString(_receiveBuffer, 0, _receiveBuffer.Length);

            string message = String.Format("[{0}]: {1}", source.Address.ToString(), dataReceived);
            Log(message, false);

            Receive();
        }, null);
}

private void Log(string message, bool isOutgoing)
{
    if (string.IsNullOrWhiteSpace(message.Trim('\0')))
    {
        return;
    }

    // Always make sure to do this on the UI thread.
    Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        string direction = (isOutgoing) ? ">> " : "<< ";
        string timestamp = DateTime.Now.ToString("HH:mm:ss");
        message = timestamp + direction + message;
        lbLog.Items.Add(message);

        // Make sure that the item we added is visible to the user.
        lbLog.ScrollIntoView(message);
    });

}

private void btnSend_Click(object sender, RoutedEventArgs e)
{
    // Don't send empty messages.
    if (!String.IsNullOrWhiteSpace(txtInput.Text))
    {
        //Send(txtInput.Text);
        SendRequest(txtInput.Text);
    }
}

private void btnStart_Click(object sender, RoutedEventArgs e)
{
    SendRequest("start now");
}

यूडीपी स्टैक का परीक्षण करने के लिए, मैंने here मिले एमएसडीएन से नमूना डाउनलोड किया और मैंने विंडोज फोन 7 डिवाइस की एक जोड़ी पर इसका परीक्षण किया और यह अपेक्षा के अनुसार काम करता है। फिर मैंने विंडोज फोन 8 में परिवर्तित कर दिया और अपने हैंडसेट पर तैनात किया, फिर से डिवाइस अपने कनेक्शन शुरू करने लगते हैं, और उपयोगकर्ता अपना नाम दर्ज कर सकते हैं। हालांकि, फिर से डिवाइस अन्य उपकरणों के साथ देख या संवाद नहीं कर सकते हैं।

अंत में मैंने नए डेटाग्राम सॉकेट कार्यान्वयन का उपयोग करके एक सरल संचार परीक्षण लागू किया, और फिर मैं सफल दीक्षा देखता हूं, लेकिन कोई इंटर-डिवाइस संचार नहीं।

डेटाग्राम सॉकेट कार्यान्वयन का उपयोग कर पृष्ठ के पीछे यह वही कोड है:

// Constructor
public MainPage()
{
    InitializeComponent();
}

// The address of the multicast group to join.
// Must be in the range from 224.0.0.0 to 239.255.255.255
private const string GROUP_ADDRESS = "224.0.1.1";

// The port over which to communicate to the multicast group
private const int GROUP_PORT = 55562;

private DatagramSocket socket = null;

private void Log(string message, bool isOutgoing)
{
    if (string.IsNullOrWhiteSpace(message.Trim('\0')))
        return;

    // Always make sure to do this on the UI thread.
    Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        string direction = (isOutgoing) ? ">> " : "<< ";
        string timestamp = DateTime.Now.ToString("HH:mm:ss");
        message = timestamp + direction + message;
        lbLog.Items.Add(message);

        // Make sure that the item we added is visible to the user.
        lbLog.ScrollIntoView(message);
    });
}

private void btnSend_Click(object sender, RoutedEventArgs e)
{
    // Don't send empty messages.
    if (!String.IsNullOrWhiteSpace(txtInput.Text))
    {
        //Send(txtInput.Text);
        SendSocketRequest(txtInput.Text);
    }
}

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    socket = new DatagramSocket();
    socket.MessageReceived += socket_MessageReceived;

    try
    {
        // Connect to the server (in our case the listener we created in previous step).
        await socket.BindServiceNameAsync(GROUP_PORT.ToString());
        socket.JoinMulticastGroup(new Windows.Networking.HostName(GROUP_ADDRESS));
        System.Diagnostics.Debug.WriteLine(socket.ToString());
    }
    catch (Exception exception)
    {
        throw;
    }
}

private async void SendSocketRequest(string message)
{
    // Create a DataWriter if we did not create one yet. Otherwise use one that is already cached.
    //DataWriter writer;
    var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(GROUP_ADDRESS), GROUP_PORT.ToString());
    //writer = new DataWriter(socket.OutputStream);
    DataWriter writer = new DataWriter(stream);

    // Write first the length of the string as UINT32 value followed up by the string. Writing data to the writer will just store data in memory.
   // stream.WriteAsync(
    writer.WriteString(message);

    // Write the locally buffered data to the network.
    try
    {
        await writer.StoreAsync();
        Log(message, true);
        System.Diagnostics.Debug.WriteLine(socket.ToString());
    }
    catch (Exception exception)
    {
        throw;
    }
    finally
    {
        writer.Dispose();
    }
}

void socket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    try
    {
        uint stringLength = args.GetDataReader().UnconsumedBufferLength;
        string msg = args.GetDataReader().ReadString(stringLength);

        Log(msg, false);
    }
    catch (Exception exception)
    {
        throw;
    }
}

कल रात मैंने अपने घर वायरलेस नेटवर्क पर परीक्षण करने के लिए हैंडसेट घर ले लिया, कम और देखो मुझे सफल डिवाइस संचार मिलता है।

तो संक्षेप में - मेरी विरासत विंडोज फोन 7 कोड मेरे काम नेटवर्क पर ठीक चलाता है। विंडोज फोन 8 के पोर्ट (कोई वास्तविक कोड परिवर्तन नहीं) इंटर-डिवाइस संचार नहीं भेजता है। यह कोड मेरे घर नेटवर्क पर काम करता है। कोड संलग्न डीबगर के साथ चलता है और निष्पादन के दौरान कहीं भी त्रुटियों या अपवादों के संकेत नहीं हैं।

मैं जिन हैंडसेट का उपयोग कर रहा हूं वे हैं:

विंडोज फोन 7 - नोकिया लुमिया 900 (* 2), नोकिया लुमिया 800 (* 3) विंडोज फोन 8 - नोकिया लुमिया 920 (* 1), नोकिया लिमिया 820 (* 2)

ये सभी नवीनतम ओएस चल रहे हैं, और डेवलपर मोड में हैं। विकास पर्यावरण विंडोज 8 एंटरप्राइज़ विजुअल स्टूडियो 2012 पेशेवर चल रहा है

मैं आपको वायरलेस नेटवर्क के बारे में बहुत कुछ नहीं बता सकता - फोन 7 उपकरणों के अलावा कोई परेशानी नहीं है।

मेरे द्वारा उपयोग किए जाने वाले घर वायरलेस नेटवर्क के लिए, यह केवल एक मूल बीटी ब्रॉडबैंड राउटर है जिसमें 'बॉक्स के बाहर' सेटिंग में से कोई भी नहीं बदला गया है।

जाहिर है कि दो नेटवर्क कॉन्फ़िगर किए गए तरीके से कोई समस्या है, लेकिन विंडोज फोन 8 यूडीपी संदेशों को लागू करने के तरीके के साथ भी एक मुद्दा स्पष्ट रूप से एक मुद्दा है।

किसी भी इनपुट की सराहना की जाएगी क्योंकि यह अभी मुझे पागल कर रहा है।


मुझे लगता है कि आप लूपबैक का उपयोग करते हैं। मुझे लगता है कि इसका मतलब है कि जब आप अपने ग्राहक से एक संदेश भेजते हैं तो आपको वह संदेश प्राप्त होगा जिसे आपने भेजा था। इसका मतलब है कि आपका प्राप्त हैंडलर आग लगेगा। यह एक अप्रत्याशित रूप से unthreadsafe फैशन में प्राप्त बफर को समाशोधन का प्रभाव है। अपनी प्राप्त विधि में कुछ प्रयास करने का प्रयास करें और देखें कि क्या कुछ भी अवांछित हो रहा है लेकिन आप किसी भी मामले में साझा प्राप्त बफर का उपयोग नहीं कर सकते हैं।


यूडीपी मल्टीकास्ट मेरे अनुभव से विंडोज फोन 7 के तहत बहुत अजीब तरह से काम करता है ताकि आपको विंडोज फोन 8 के लिए चेकआउट करना चाहिए।

मेरा अनुभव यहां है:

  1. जांचें कि आधिकारिक रूप से समर्थित है, उदाहरण के लिए विंडोज फोन ओएस 7.1 (अंतिम ओएस मैंने स्विच करने से पहले कोशिश की) के तहत, टीसीपी यूनिकास्ट, यूडीपी यूनिकास्ट, और यूडीपी मल्टीकास्ट क्लाइंट समर्थित हैं।
  2. विंडोज फोन के कुछ संस्करण केवल यूडीपी सत्र प्राप्त करने की अनुमति देते हैं यदि क्लाइंट ने इसे पहली बार खोला है और सत्र 10 सेकंड से अधिक के भीतर प्राप्त नहीं होता है, यह विंडोज फोन पर किसी प्रकार की सुरक्षा चीज़ की तरह लगता है।
  3. विभिन्न पतों के साथ प्रयास करें: 224.0.0.0 से 224.0.0.255 तक की श्रेणी में मल्टीकास्ट पते शामिल हैं "जाने-माने" आरक्षित मल्टीकास्ट पते।
  4. वर्चुअल मशीन और वास्तविक फोन डिवाइस दोनों में जांचें, व्यवहार भिन्न हो सकता है।

लुसेरो के जवाब पर बिल्डिंग, यहां एक तेज संस्करण है। यह प्रत्येक पुनरावृत्ति Buffer.BlockCopy का उपयोग करके कॉपी किए गए बाइट्स की संख्या को दोगुना कर देगा। दिलचस्प बात यह है कि यह अपेक्षाकृत छोटे सरणी (1000) का उपयोग करते समय 10 के कारक से बेहतर प्रदर्शन करता है, लेकिन अंतर बड़ा सरणी (1000000) के लिए बड़ा नहीं है, हालांकि यह हमेशा तेज होता है। इसके बारे में अच्छी बात यह है कि यह छोटे सरणी तक भी अच्छा प्रदर्शन करता है। यह लगभग लंबाई = 100 पर निष्पक्ष दृष्टिकोण से तेज़ हो जाता है। एक मिलियन तत्व बाइट सरणी के लिए, यह 43 गुना तेज था। (इंटेल i7, .NET 2.0 पर परीक्षण किया गया)

public static void MemSet(byte[] array, byte value) {
    if (array == null) {
        throw new ArgumentNullException("array");
    }

    int block = 32, index = 0;
    int length = Math.Min(block, array.Length);

    //Fill the initial array
    while (index < length) {
        array[index++] = value;
    }

    length = array.Length;
    while (index < length) {
        Buffer.BlockCopy(array, 0, array, index, Math.Min(block, length-index));
        index += block;
        block *= 2;
    }
}




c# sockets udp windows-phone-8 datagram