Question

I am sending udp unicast packets from windows to linux .

I have written simple application udp client and srever using boost .

I am running client(udp sender) on windows and server (udp receiver ) on linux .

my client is sending the udp packets but my udp receiver on linux is not receiving the packets . but I could see the udp packets on the wireshark(which is running on my linux pc) .

I tested the port and ipaddress , all are proper .

below is the code which is running on linux.

If I run both(Client and server) on windows , it works fine

using boost::asio::ip::udp;

class udp_server
{
public:
  udp_server(boost::asio::io_service& io_service)
    : socket_(io_service, udp::endpoint(udp::v4(), 7799))
  {
    start_receive();
  }

private:
  void start_receive()
  {
    socket_.async_receive_from(
        boost::asio::buffer(recv_buffer_), remote_endpoint_,
        boost::bind(&udp_server::handle_receive, this,
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
  }

  void handle_receive(const boost::system::error_code& error,
      std::size_t /*bytes_transferred*/)
  {
    if (!error || error == boost::asio::error::message_size)
    {

      start_receive();
    }
  }

  udp::socket socket_;
  udp::endpoint remote_endpoint_;
  boost::array<char, 1> recv_buffer_;
};

int main()
{
  try
  {
    boost::asio::io_service io_service;
    udp_server server(io_service);
    io_service.run();
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

return 0;
}
Was it helpful?

Solution

UDP is a datagram protocol. The protocol is stateless, and packets need to be received as a single packet.

See Beej's Guide to Networking for background information.

Your receive buffer, however, is 1 byte. You can not expect to read more than the first byte.

This looks like it may be copied from e.g. tutorial 6 listing. The difference is, that was a daytime service which doesn't care about the request. All that it wants to know is that "a packet was received" and it will just send the daytime response unconditionally.

So, a solution would seem to be to increase the buffer size. If the size of package cannot be predicted/is not bounded, consider switching to stream sockets (TCP/IP).

Here, as a bonus, using c++11 style:

#include <boost/asio.hpp>

using boost::asio::ip::udp;

class udp_server
{
    public:
        udp_server(boost::asio::io_service& io_service)
            : socket_(io_service, udp::endpoint(udp::v4(), 7799))
        {
            start_receive();
        }

    private:
        void start_receive()
        {
            socket_.async_receive_from(
                boost::asio::buffer(recv_buffer_), remote_endpoint_,
                [this](boost::system::error_code ec, std::size_t bytes_transferred)
                {
                    if (!ec && (bytes_transferred > 0))
                    {
                        std::cout << "PACKET[" << std::string(&recv_buffer_[0], &recv_buffer_[0]+bytes_transferred) << "]\n";
                    } else
                        throw ec; // TODO
                    start_receive();
                });
        }

        udp::socket socket_;
        char recv_buffer_[1024];
        udp::endpoint remote_endpoint_;
};

int main()
{
    std::cout << std::unitbuf;
    try
    {
        boost::asio::io_service io_service;
        udp_server server(io_service);
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top