Lichtso / netLink

Socket and Networking Library using msgpack.org[C++11]
GNU General Public License v3.0
216 stars 48 forks source link

Broadcasting with listening #19

Closed DJuego closed 7 years ago

DJuego commented 7 years ago

Again me, Lichtso! Hi! :-D During these months I have been with other projects but I am back. 👍

I have several problems with this code (i have isolated the problems from my super-project. :-D):

[Link to pastecode]

I feel the code is so big but at least it's complete and it can be run.

I am working in Windows 10 x64 with Visual Studio 2015.

1) I have two computers in a LAN. The Sender and The Receiver. I am broadcasting UDP packets from the Sender. However i want The Sender can listen too.

a) The Receiver only receive a packet! :-((( However if the Receiver and The Sender run in the same computer the program works. b) In The Sender, the socket receives its own packet (I suspect this has to do with the cause of the problem) c) This program works perfectly if the line socketManager.listen(5.0); is commented (in The Sender).

Questions: Q1: The socket receives its own packet. Can this behavior be avoided? Q2: Does this mean that it is not possible to listen from a socket that is broadcasting ?

[PD: Really now i understand perfectly that the answers are: A1: No. The behaviour is correct! A2: No. This mean you should'nt do it. :-D

]


#include <iostream>
#include <chrono>
#include <string>
#include <netLink/netLink.h>

char data[128];

void wait(int milliseconds)
{

    std::chrono::high_resolution_clock::time_point end, start;
    std::chrono::milliseconds ms;

    start = std::chrono::high_resolution_clock::now();
    do
    {
        end = std::chrono::high_resolution_clock::now();
        ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    } while (ms.count() < milliseconds);
}

int main(int argc, char** argv) {
    //#ifdef WINVER
    netLink::init();
    //#endif

    netLink::SocketManager socketManager;
    std::shared_ptr<netLink::Socket> socket = socketManager.newSocket();
    try
    {
        socket->initAsUdpPeer("0.0.0.0", 3015);
    }
    catch (netLink::Exception exc)
    {
        std::cout << "Address is already in use" << std::endl;
        return 1;
    }
    socket->setBlockingMode(false);

    if (argc > 1)
    {
        std::cout << "The Receiver" << std::endl;
        socketManager.onReceiveRaw = [](netLink::SocketManager *manager, std::shared_ptr< netLink::Socket > socket)
        {

            std::cout << "Receiving..." << std::endl;
            std::size_t size = socket->sgetn(data, 128);
            //std::size_t size = socket->receive(data, 128);
            if (size > 0)
            {
                std::cout << "Incoming data: " << data << std::endl;
            }
            else
            {
                std::cout << "NO DATA???" << std::endl;
            }

        };

        while (true)
            socketManager.listen(5.0);

    }
    else
    {
        std::cout << "The Sender" << std::endl;

        socket->setBroadcast(true);
        socket->hostRemote = "255.255.255.255";
        socket->portRemote = socket->portLocal; 

        char* data = "My data\0";

        while (true)
        {

            wait(1000);

            std::cout << "Listening..." << std::endl;
            socketManager.listen(5.0); //THIS LINE IS PROBLEMATIC. THE PROGRAM DOES NOT WORK!!! :-(

            std::cout << "Sending..." << std::endl;
            std::streamsize size = socket->send(data, 128);

        }

    }
    return 0;
}
Lichtso commented 7 years ago

So as I understood it, you want to: Send a broadcast UDP packet, without receiving your own packets only packet from others.

Well this behavior is often called loopback in networking. But the real question is, why use the old broadcast if you could use the newer multicast, which also works in IPv6 and can be controlled better? Take a look at: Socket::setMulticastGroup

DJuego commented 7 years ago

Yes, yes. I know multicast. Thank you for supporting! A great idea. 👍

However i am triyng to mimic the behaviour of EV3 brick with the official firmware (from LEGO). The brick broadcast UDP packets with the old broadcast. More info here. :-D

Anyway I've noticed i do not need to listen the broadcasting udp port. for my purposes :-P So, really, this 'issue' is not important for me. :-P

Simpy, i just wondered why the "loopback" causes me network problems (The Receiver only receive the first packet and no more [NOTE: two different computers in LAN])

DJuego