MiXen

Sending and receiving UDP broadcast message in C++ in Windows Phone.

Recommended Posts

Hi!

I looking for example of sending and receving UDP Datagram broadcast message. I only find examples in C#, but I write my project in C++ and I don't know, how can I rewrite it. I know, that I must use DatagramSocket class. Maybe someone has similar problem. Thanks for ony help.

 

Share this post


Link to post
Share on other sites

Yes, I look it there, but I'm new in internet programming, so I can't remake this sample in that way, that I want. Maybe do you have something closer to my problem?

 

According to my previous post to person, that gave me minus point, come on! I get drawbacks for what? For saying, that moderator isn't read carefully? No comment...

Share this post


Link to post
Share on other sites

 

I look it there, but I'm new in internet programming, so I can't remake this sample in that way, that I want. Maybe do you have something closer to my problem?

 

 

In that case, start here.

 

That information on those links have helped thousands of people do what you wanted to do.  

 

It requires work. There is no magic component you can download that does everything for you. The information is generic and applies to most situations, you must take the information, do some work, and turn it into something that works in your product.

 

 

Some follow up questions:

 

What have you actually done so far? What books, tutorials, and documentation have you already used and exhausted? What FAQs have you read? 

 

And most importantly: What SPECIFICALLY about it does not work for you?   That is, when you attempted to implement it in your program, what specific parts failed?

Share this post


Link to post
Share on other sites

Ok, maybe nobody didn't make it for me, but giving me minus point for saying truth is ridiculus.

 

Backing to threat, I started from remake this datagram sample and I have one big problem, that broadcasting isn't working. My computer has adress in LAN:192.168.2.103, when I set this in program, I get message sending by its, but when I set brooadcasting adress 192.168.2.255 or 255.255.255.255, I didn't get message in this sample, can anybody help me with it?

Share this post


Link to post
Share on other sites
Did you enable broadcast on the socket?
What tool do you use to test whether it "works" or not?
What does Wireshark say about outgoing UDP packets while you're trying to broadcast?

Also, there are more examples of this, such as: http://metronuggets.com/2013/03/18/how-to-send-and-receive-a-udp-broadcast-in-windows-phone-8-and-win8/
If you run this code, does that work? If so, what's different about your own code?

Share this post


Link to post
Share on other sites

Only omniscient beings, oracles, and time travelers can help you if you don't post your code...

 

"datagram sample" two post ealier : https://code.msdn.microsoft.com/windowsapps/DatagramSocket-sample-76a7d82b Scroll is hard?

Pleasse... Do you develop for WinRT platforms? ...

 

Did you enable broadcast on the socket?
What tool do you use to test whether it "works" or not?
What does Wireshark say about outgoing UDP packets while you're trying to broadcast?

Also, there are more examples of this, such as: http://metronuggets.com/2013/03/18/how-to-send-and-receive-a-udp-broadcast-in-windows-phone-8-and-win8/
If you run this code, does that work? If so, what's different about your own code?

Broadcast is enabled, I check, if I get a message from host in this sample.

I found this tutorial ealier? Did you notice, that this code is in C#? ...

 

I try to remake this sample and I done this including it to my app. Now I see, that listener and sender is create properly and data was send, but I didn't get this send data returing to the listener. I don't know, what is wrong with it. This is my code:

void gameMenu::CreateUDPListener(Platform::String^ port)
{
    
    listener = ref new DatagramSocket();
    listenerContext = ref new ListenerContextUDP(listener);
    listener->MessageReceived += ref new TypedEventHandler<DatagramSocket^, DatagramSocketMessageReceivedEventArgs^>(listenerContext, &ListenerContextUDP::OnMessage);
    create_task(listener->BindServiceNameAsync(port)).then([this](task<void> previousTask)
    {
        try
        {
            FW1_RECTF rect;
            // Try getting an exception.
            previousTask.get();
            rect = { 50.0f, 200.0f, 2500.0f, 200.0f };
            fontWrapper->AnalyzeString(NULL, L"listener!", L"Segoe UI", 0.0146f*width, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
        }
        catch (Exception^ exception)
        {
            FW1_RECTF rect;
            rect = { 50.0f, 350.0f, 2500.0f, 350.0f };
            fontWrapper->AnalyzeString(NULL, L"error 1", L"Segoe UI", 0.0146f*width, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
        }
    });
}

void gameMenu::CreateUDPSender(Windows::Networking::HostName^ hostName, Platform::String^ port)
{
    socket = ref new DatagramSocket();
    SocketContextUDP^ socketContextInside = ref new SocketContextUDP(socket, devRes);
    socket->MessageReceived += ref new TypedEventHandler<DatagramSocket^, DatagramSocketMessageReceivedEventArgs^>(socketContextInside, &SocketContextUDP::OnMessage);
    create_task(socket->ConnectAsync(hostName, port)).then([this, socketContextInside](task<void> previousTask)
    {
        try
        {
            // Try getting an exception.
            previousTask.get();
            socketContextInside->SetConnected();
            socketContext = socketContextInside;
            FW1_RECTF rect;
            rect = { 50.0f, 250.0f, 2500.0f, 250.0f };
            fontWrapper->AnalyzeString(NULL, L"sender!", L"Segoe UI", 0.0146f*width, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
        }
        catch (Exception^ exception)
        {
            FW1_RECTF rect;
            rect = { 50.0f, 350.0f, 2500.0f, 350.0f };
            fontWrapper->AnalyzeString(NULL, L"error 2", L"Segoe UI", 0.0146f*width, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
        }
    });
}

void gameMenu::SendDataOverUDP(String^ data)
{
    if (!socketContext->IsConnected())
    {
        FW1_RECTF rect;
        rect = { 50.0f, 300.0f, 2500.0f, 300.0f };
        fontWrapper->AnalyzeString(NULL, L"no sender", L"Segoe UI", 0.0146f*width, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
        return;
    }
    create_task(socketContext->GetWriter()->StoreAsync()).then(
        [this, data](task<unsigned int> writeTask)
    {
        try
        {
            // Try getting an excpetion.
            writeTask.get();
            FW1_RECTF rect;
            rect = { 50.0f, 300.0f, 2500.0f, 300.0f };
            fontWrapper->AnalyzeString(NULL, L"data send!", L"Segoe UI", 0.0146f*width, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
            //SendOutput->Text = "\"" + stringToSend + "\" sent successfully";
        }
        catch (Exception^ exception)
        {
            FW1_RECTF rect;
            rect = { 50.0f, 350.0f, 2500.0f, 350.0f };
            fontWrapper->AnalyzeString(NULL, L"error 3", L"Segoe UI", 0.0146f*width, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
        }
    });
}

SocketContextUDP::SocketContextUDP(DatagramSocket^ socket, const std::shared_ptr<DX::DeviceResources>& deviceResources) :
devRes(deviceResources)
{
    this->socket = socket;
    this->connected = false;
}

SocketContextUDP::~SocketContextUDP()
{
    // The socket (data writer) can be closed in two ways:
    //  - explicit: by using delete operator (the socket or the stream used by data writer is closed even if there
    //    are outstanding references to the objects).
    //  - implicit: by removing last reference to it (i.e. falling out-of-scope).
    // In this case this is the last reference to the socket and data writer so both will yield the same result.
    delete socket;
    socket = nullptr;

    if (writer != nullptr)
    {
        delete writer;
        writer = nullptr;
    }
}

void SocketContextUDP::OnMessage(DatagramSocket^ socket, DatagramSocketMessageReceivedEventArgs^ eventArguments)
{
    try
    {
        unsigned int stringLength = eventArguments->GetDataReader()->UnconsumedBufferLength;
        FW1_RECTF rect;
        rect = { 50.0f, 400.0f, 2500.0f, 400.0f };
        menu->GetWrapper()->AnalyzeString(NULL, L"receive data", L"Segoe UI", 0.0146f*1920.0f, &rect, 0xffffffff, FW1_NOFLUSH, menu->GetMainGeometry());
        //NotifyUserFromAsyncThread("Receive data from remote peer: \"" + eventArguments->GetDataReader()->ReadString(stringLength) + "\"",NotifyType::StatusMessage);
    }
    catch (Exception^ exception)
    {
        SocketErrorStatus socketError = SocketError::GetStatus(exception->HResult);
        if (socketError == SocketErrorStatus::ConnectionResetByPeer)
        {
            FW1_RECTF rect;
            rect = { 50.0f, 400.0f, 2500.0f, 400.0f };
            menu->GetWrapper()->AnalyzeString(NULL, L"err1", L"Segoe UI", 0.0146f*1920.0f, &rect, 0xffffffff, FW1_NOFLUSH, menu->GetMainGeometry());
        }
        else if (socketError != SocketErrorStatus::Unknown)
        {
            FW1_RECTF rect;
            rect = { 50.0f, 400.0f, 2500.0f, 400.0f };
            menu->GetWrapper()->AnalyzeString(NULL, L"err2", L"Segoe UI", 0.0146f*1920.0f, &rect, 0xffffffff, FW1_NOFLUSH, menu->GetMainGeometry());
        }
        else
        {
            FW1_RECTF rect;
            rect = { 50.0f, 400.0f, 2500.0f, 400.0f };
            menu->GetWrapper()->AnalyzeString(NULL, L"err3", L"Segoe UI", 0.0146f*1920.0f, &rect, 0xffffffff, FW1_NOFLUSH, menu->GetMainGeometry());
            throw;
        }
    }
}

DataWriter^ SocketContextUDP::GetWriter()
{
    if (writer == nullptr)
    {
        writer = ref new DataWriter(socket->OutputStream);
    }

    return writer;
}

boolean SocketContextUDP::IsConnected()
{
    return connected;
}

void SocketContextUDP::SetConnected()
{
    connected = true;
}

void ListenerContextUDP::OnMessage(DatagramSocket^ socket, DatagramSocketMessageReceivedEventArgs^ eventArguments)
{
    if (outputStream != nullptr)
    {
        EchoMessage(eventArguments);
        return;
    }

    // We do not have an output stream yet so create one.
    create_task(socket->GetOutputStreamAsync(eventArguments->RemoteAddress, eventArguments->RemotePort)).then(
        [this, socket, eventArguments](IOutputStream^ stream)
    {
        // It might happen that the OnMessage was invoked more than once before the GetOutputStreamAsync completed.
        // In this case we will end up with multiple streams - make sure we have just one of it.
        EnterCriticalSection(&lock);

        if (outputStream == nullptr)
        {
            outputStream = stream;
            hostName = eventArguments->RemoteAddress;
            port = eventArguments->RemotePort;
        }

        LeaveCriticalSection(&lock);

        EchoMessage(eventArguments);
    }).then([this, socket, eventArguments](task<void> previousTask)
    {
        try
        {
            // Try getting all exceptions from the continuation chain above this point.
            previousTask.get();
        }
        catch (Exception^ exception)
        {
            //NotifyUserFromAsyncThread("Getting an output stream failed with error: " + exception->Message,NotifyType::ErrorMessage);
        }
    });
}

ListenerContextUDP::ListenerContextUDP(DatagramSocket^ listener)
{
    this->listener = listener;
    InitializeCriticalSectionEx(&lock, 0, 0);
}

ListenerContextUDP::~ListenerContextUDP()
{
    // The listener can be closed in two ways:
    //  - explicit: by using delete operator (the listener is closed even if there are outstanding references to it).
    //  - implicit: by removing last reference to it (i.e. falling out-of-scope).
    // In this case this is the last reference to the listener so both will yield the same result.
    delete listener;
    listener = nullptr;

    DeleteCriticalSection(&lock);
}

void ListenerContextUDP::EchoMessage(DatagramSocketMessageReceivedEventArgs^ eventArguments)
{
    if (!IsMatching(eventArguments->RemoteAddress, eventArguments->RemotePort))
    {
        // In the sample we are communicating with just one peer. To communicate with multiple peers application
        // should cache output streams (i.e. by using a hash map), because creating an output stream for each
        // received datagram is costly. Keep in mind though, that every cache requires logic to remove old
        // or unused elements; otherwise cache turns into a memory leaking structure.
        //NotifyUserFromAsyncThread("Got datagram from " + eventArguments->RemoteAddress->DisplayName + ":" +eventArguments->RemotePort + ", but already 'connected' to " + hostName->DisplayName + ":" +port, NotifyType::ErrorMessage);
    }

    create_task(outputStream->WriteAsync(eventArguments->GetDataReader()->DetachBuffer())).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);
        }
    });
}

bool ListenerContextUDP::IsMatching(HostName^ hostName, String^ port)
{
    return (this->hostName == hostName && this->port == port);
}

Edit for ankhd:

Boost.ASIO depends on the WinSock API, which just recently is now allowed on Windows Phone 8. However I'd bet that ASIO is using other APIs that are banned, that you'd have to replace.

No comment...

Edited by MiXen

Share this post


Link to post
Share on other sites

Did you notice, that this code is in C#?


The translation betweem C++/CLR and C# should be pretty simple, if you need to do it.
Also, Microsoft samples are often available in many languages if you look -- I don't know about this one in particular.

Finally, if you already tracked down that the packet makes it to the receiver, but the process doesn't get it, then what have you done to debug that problem?
Have you enabled broadcast on the receiver?
Are you binding to the right port?
What does Wireshark say on the receiving machine?

Share this post


Link to post
Share on other sites

My code from previous post is port from this C# code to C++/CX and this code based on Microsoft sample. Did you see the previous linked datagram sample?

 

I use wireshark and I see, that isn't any data send to the network. Broadcast is enabled, port of receiver and sender is matching.

Share this post


Link to post
Share on other sites
In the previoius message, you said that data was sent to the recipient, but it wasn't actually received by the receiving program.
In this latest message, you say that data isn't actually being sent from the sending program to the network.
Which one is it?

It's very hard to try to help you when you don't actually answer the questions we're asking to try to help you.

If you run the metronuggets code on sender and receiver, does it work?

Share this post


Link to post
Share on other sites

I didn't know, that sender didn't send data to the network, because I think it does. I've checked it by wireshark and I discover this. I notice, that after send data, sender and receiver should activatet function OnMessage from my code, but it doesn't. I don't know why?

 

I cannot run metronuggest code, because my project isn't in c#.

Share this post


Link to post
Share on other sites

Yea, come on! Give drawback. This forum is a group of imbecile, no one help, everybody can give minus points.... One of the most popular forums in this threat, you should shame of this!

Edited by MiXen

Share this post


Link to post
Share on other sites

I cannot run metronuggest code, because my project isn't in c#.


If you can't run that example to compare with, then you can't figure out whether the problem is your networking hardware, your computer/OS, or your own code, or something else.

I think this forum has exhausted its ability to read your mind, and its ability to help you when you don't actually try all the things suggested, and don't actually answer all the questions asked. If you want someone to write your code for you and/or lead you to the solution in person, I suggest hiring a contractor.

Share this post


Link to post
Share on other sites

I don't know. I try to rewrite this metronuggest code to c++ and I get this:

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("192.168.0.11");
//        listener->JoinMulticastGroup(MyHostName);

        task<IOutputStream^>(listener->GetOutputStreamAsync(MyHostName, "22345")).then([this](IOutputStream^ stream)
        {

            String^ stringToSend("Hello");
            DataWriter^ writer = ref new DataWriter(stream);
            writer->WriteString(stringToSend);
            create_task(writer->StoreAsync()).then([this](task<unsigned int> writeTask)
            {
                try
                {
                    FW1_RECTF rect;
                    rect = { 50.0f, 300.0f, 2500.0f, 300.0f };
                    fontWrapper->AnalyzeString(NULL, L"data send!", L"Segoe UI", 0.0146f*width, &rect, 0xffffffff, FW1_NOFLUSH, textMainGeometry);
                    writeTask.get();
                }
                catch (Exception^ exception)
                {
                    if (SocketError::GetStatus(exception->HResult) == SocketErrorStatus::Unknown)
                    {
                        throw;
                    }

                }
            });
        });
    });

I think, that it is similar to this in C#, but is doesn't work, anybody know, why?(in wireshark I didn't see any packets in network)

Share this post


Link to post
Share on other sites

I don't know. I try to rewrite this metronuggest code to c++ and I get this:


If you're not going to actually follow the questions and instructions that people offer in this thread, you are very unlikely to get good help from the thread.

You said:

DatagramSample runs very well


I asked:

Does the datagram sample run well with broadcast?


You said:

I don't know.


I suggest that you actually change the datagram sample to use broadcast, without porting anything to another language.
If you can make that run well with broadcast, then you can prove that your network and hardware is not the problem.
If you cannot make that run with broadcast, then it's possible that your network is the problem.

Share this post


Link to post
Share on other sites

 

I don't know. I try to rewrite this metronuggest code to c++ and I get this:


If you're not going to actually follow the questions and instructions that people offer in this thread, you are very unlikely to get good help from the thread.

You said:

DatagramSample runs very well


I asked:

Does the datagram sample run well with broadcast?


You said:

I don't know.


I suggest that you actually change the datagram sample to use broadcast, without porting anything to another language.
If you can make that run well with broadcast, then you can prove that your network and hardware is not the problem.
If you cannot make that run with broadcast, then it's possible that your network is the problem.

 

 

Ok, If you want to know, I reply to you: Broadcast of datagram sample runs really strengly, When I send datagram from PC, I get it on the phone, but when I send it on the phone, I don't get it on the PC, I don't know why, so I start to remake this short code, but it didn't runs well. Can you look at it and say, what can be wrong with it?

Share this post


Link to post
Share on other sites

When I send datagram from PC, I get it on the phone, but when I send it on the phone, I don't get it on the PC,


Maybe the phone hardware or networking doesn't actually support broadcasts?

Can you look at it and say, what can be wrong with it?


What have you tried to do yourself in debugging?
If you put a breakpoint and step through the code, what happens?
What do you expect to happen differently?

Share this post


Link to post
Share on other sites

 

When I send datagram from PC, I get it on the phone, but when I send it on the phone, I don't get it on the PC,


Maybe the phone hardware or networking doesn't actually support broadcasts?

Can you look at it and say, what can be wrong with it?


What have you tried to do yourself in debugging?
If you put a breakpoint and step through the code, what happens?
What do you expect to happen differently?

 

This code runs well, so I don't get any exeptions. I see a send packet in wireshark, but I don't get a info about messagereceive. I don't get it why. When I have a packet in LAN, messagereceive from datagramsocket should get it, but it doesn't, why?

Edited by MiXen

Share this post


Link to post
Share on other sites

I see a send packet in wireshark, but I don't get a info about messagereceive.


In Wireshark, do you see the correct broadcast address and port?

If so, it's likely that your listening port or some other listening filter (which may include the machine firewall) are incorrect on the socket.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.