locked
Problem with sending Datagram to Multicast in LAN.

    Question

  • Hi,

    in my project I want to send a multicast datagram to find other devices in my lan and I have problem with code, that he doesn't send anything. Here it is:

    listener = ref new DatagramSocket();
    	listenerContext = ref new ListenerContextUDP(listener);
    	listener->MessageReceived += ref new TypedEventHandler<DatagramSocket^, DatagramSocketMessageReceivedEventArgs^>(listenerContext, &ListenerContextUDP::OnMessage);
    	create_task(listener->BindServiceNameAsync("22345")).then([this](task<void> previousTask)
    	{
    		HostName^ MyHostName = ref new HostName("239.192.168.22");
    		listener->JoinMulticastGroup(MyHostName);
    
    		task<IOutputStream^>(listener->GetOutputStreamAsync(MyHostName, "22345")).then([this](IOutputStream^ stream)
    		{
    
    			std::wstring foo(L"32");
    			auto bar = static_cast<unsigned char>(std::stol(foo));
    			create_task(stream->WriteAsync((IBuffer^)bar)).then(
    				[this](task<unsigned int> writeTask)
    			{
    				try
    				{
    					// Try getting an exception.
    					writeTask.get();
    				}
    				catch (Exception^ exception)
    				{
    					//NotifyUserFromAsyncThread("Echoing a message failed with error: " + exception->Message,NotifyType::ErrorMessage);
    				}
    			});
    		});
    	});
    My OnMessage function:
    void SocketContextUDP::OnMessage(DatagramSocket^ socket, DatagramSocketMessageReceivedEventArgs^ eventArguments)
    {
    	FW1_RECTF rect;
    	rect = { 50.0f, 400.0f, 2500.0f, 400.0f };
    	fontWrapper->AnalyzeString(NULL, L"receive data", L"Segoe UI", 0.0146f*1920.0f, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
    }
    

    This code should work along with documentation about DatagramSocket. Anybody knows what is wrong with it?

    My second question is how can I convert a string message to Ibuffer message? I cannot find something usefull in internet?

    Monday, April 20, 2015 9:28 AM

All replies

  • Here's the code that I use for network discovery. You're using a the version of BindServiceNameAsync that does not take an adapter as a parameter. Also I don't see where you call previousTask->get().

    	socket = ref new DatagramSocket;
    	socket->MessageReceived += ref new TypedEventHandler<DatagramSocket^, DatagramSocketMessageReceivedEventArgs^>(this, &ZeroConfigResolver::OnMessage);
    
    	ConnectionProfile^ connectionProfile = NetworkInformation::GetInternetConnectionProfile();
    
    	task<void>(socket->BindServiceNameAsync("5353", connectionProfile->NetworkAdapter)).then([this, _protocol] (task<void> previousTask)
    	{
    		try 
    		{
    			previousTask.get();
    			socket->JoinMulticastGroup(ref new HostName("224.0.0.251"));
    
    			IAsyncOperation<IOutputStream^> ^op = socket->GetOutputStreamAsync(ref new HostName("224.0.0.251"), "5353");
    
    			op->Completed = ref new AsyncOperationCompletedHandler<IOutputStream^>
    				([this, _protocol](IAsyncOperation<IOutputStream^> ^op, Windows::Foundation::AsyncStatus status)
    			{
    
    				auto ec = op->ErrorCode;
    				IOutputStream ^ostream = op->GetResults();
    
    				DataWriter	^writer = ref new DataWriter(ostream);
    
    				std::wstring p = _protocol->Data();
    				this->WriteQueryMessage(p, writer);
    				writer->StoreAsync();
    			});
    

    I didn't include the catch, but that should not matter for purposes of an example.

    In my code WriteQueryMessage is a member method that writes the network discovery query to the writer. I hope this help.

    Tuesday, April 21, 2015 12:20 AM
  • Thanks for reply. I remake your code for my app, but my OnMessage function still doesn't get run. Can you tell me why?

    socket = ref new DatagramSocket;
                listenerContext = ref new ListenerContextUDP(socket);
                socket->MessageReceived += ref new TypedEventHandler<DatagramSocket^, DatagramSocketMessageReceivedEventArgs^>(listenerContext, &ListenerContextUDP::OnMessage);
    
                Windows::Networking::Connectivity::ConnectionProfile^ connectionProfile = Windows::Networking::Connectivity::NetworkInformation::GetInternetConnectionProfile();
    
                task<void>(socket->BindServiceNameAsync("5353", connectionProfile->NetworkAdapter)).then([this](task<void> previousTask)
                {
                    try
                    {
                        previousTask.get();
                        socket->JoinMulticastGroup(ref new HostName("224.0.0.251"));
    
                        IAsyncOperation<IOutputStream^> ^op = socket->GetOutputStreamAsync(ref new HostName("224.0.0.251"), "5353");
    
                        op->Completed = ref new AsyncOperationCompletedHandler<IOutputStream^>
                            ([this](IAsyncOperation<IOutputStream^> ^op, Windows::Foundation::AsyncStatus status)
                        {
    
                            auto ec = op->ErrorCode;
                            IOutputStream ^ostream = op->GetResults();
    
                            DataWriter    ^writer = ref new DataWriter(ostream);
    
                            String^ stringToSend("Hello2");
                            writer->WriteString(stringToSend);
                            writer->StoreAsync();
                        });
                    }
                    catch (Exception^ exception)
                    {}
                });

    I want to add, that in wireshark I see send packets to the LAN.

    Edit: This is dump from wireshark :5597    60.148899000    192.168.0.11    224.0.0.251    MDNS    48    Unknown operation (13) 0x4865 [Malformed Packet] This is sometype of error, any help? :)
    • Edited by MiXenXd Tuesday, April 21, 2015 1:26 PM
    Tuesday, April 21, 2015 12:08 PM
  • I really don't know. Maybe your query string is wrong, firewall is blocking it, there are no devices on the network that will reply to your query?
    Tuesday, April 21, 2015 1:50 PM
  • I try running my app on PC and phone, and no one isn't responding on it, so I know, that it isn't problem with firewall, because in phone it is impossible :) Can you give code of your function WriteQueryMessage, because I think, that my problem is here?
    Tuesday, April 21, 2015 4:09 PM
  • Your best bet is to take a look at Sergey Aldoukhov's excellent implementation of ZeroConfig in WinRT. It's C# but it has all the examples you need.

    https://github.com/saldoukhov/ZeroconfRT

    Tuesday, April 21, 2015 4:55 PM
  • I know but in C# we can easily convert from string to bytes array, but in managed c++, we can't. I wonder, how can you convert std::wstring line to IBuffer and saving it to DataWriter?
    Tuesday, April 21, 2015 5:11 PM
  • Why would you need to use IBuffer? std::wstring can be converted to String^ (there's lots of examples out there). Then use DataWriter::WriteString.
    Tuesday, April 21, 2015 6:22 PM
  • I thought, that you are doing this different than me, but I see, you don't, so I don't know, what is happening? I see thought wireshark, that my datagram is send to the lan, but none of my devices get it. Please, help me, I'm working on it in third week, but it still don't working. WHY MICROSOFT WHY?!
    Tuesday, April 21, 2015 6:49 PM