Boost C++ UDP example can not transmit over internet

筅森魡賤 提交于 2019-12-12 05:00:02

问题


Hello i am experimenting with Boost C++ UDP client-server.

I took the one of the examples that comes with ASIO and modified it a bit.

It works very well on local network but when i host the server to one of our servers with ports correctly forwarded, it doesn't work.

I run the UDP server and try to transmit with the client from home over the internet but none of the packets arrive to the server. I am sure that the ports are forwarded correctly and that the firewall is not getting in the way.

Is there any difference between local network and internet as far as UDP communication is concerned?

Following is the code of client and server:

----Client----

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <boost/asio.hpp>

using boost::asio::ip::udp;
enum { max_length = 1024 };

int main(int argc, char* argv[])
{
char request[max_length];
try
{

    boost::asio::io_service io_service;

    udp::socket s(io_service, udp::endpoint(udp::v4(), 0));

    udp::resolver resolver(io_service);
    udp::resolver::query query(udp::v4(), "MyPublicIp", "3002");
    udp::resolver::iterator iterator = resolver.resolve(query);

    using namespace std; // For strlen.
    std::cout << "Write to me: ";
    while(1)
    {
        std::cin.getline(request, max_length);
        size_t request_length = strlen(request);
        s.send_to(boost::asio::buffer(request, request_length), *iterator);

        char reply[max_length];
        udp::endpoint sender_endpoint;
        size_t reply_length = s.receive_from(boost::asio::buffer(reply, max_length), sender_endpoint);
        std::cout << Say:";
        std::cout.write(reply, reply_length);
        std::cout << "\n";
        std::cout << Say What?" ;
    }
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }
  std::cin.getline(request, max_length);
  return 0;
}

------Server------------

#include <boost/chrono.hpp>
#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost\thread\thread.hpp>
#include <ctime>
using boost::asio::ip::udp;

class server
{
public:
  server(boost::asio::io_service& io_service, short port)
    : io_service_(io_service),
      socket_(io_service, udp::endpoint( boost::asio::ip::address_v4::any(), port))
  {
      std::fill(data_, data_ + max_length, 0);
    socket_.async_receive_from(
        boost::asio::buffer(data_, max_length), sender_endpoint_,
        boost::bind(&server::handle_receive_from, this,
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
  }

  void handle_receive_from(const boost::system::error_code& error,
      size_t bytes_recvd)
  {
    if (!error && bytes_recvd > 0)
    {
        td::cout  << "Connection from: " << sender_endpoint_.address().to_string() << " " << sender_endpoint_.port() << std::endl;

      socket_.async_send_to(
          boost::asio::buffer(data_, strlen(data_)), sender_endpoint_,
          boost::bind(&server::handle_send_to, this,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
    }
    else
    {
      socket_.async_receive_from(
          boost::asio::buffer(data_, max_length), sender_endpoint_,
          boost::bind(&server::handle_receive_from, this,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
    }
  }

  void handle_send_to(const boost::system::error_code& /*error*/,
      size_t /*bytes_sent*/)
  {  

      std::fill(data_, data_ + max_length, 0);
    socket_.async_receive_from(
        boost::asio::buffer(data_, max_length), sender_endpoint_,
        boost::bind(&server::handle_receive_from, this,
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));

  }

private:
  boost::asio::io_service& io_service_;
  udp::socket socket_;
  udp::endpoint sender_endpoint_;
  enum { max_length = 300 };
  char data_[max_length];
};

int main(int argc, char* argv[])
{
  try
  {
    std::cout << "Starting server" << std::endl;

    boost::asio::io_service io_service;
    short port = 3002;
    using namespace std; 
    server s(io_service, port);
    std::cout << "Server started. Listening on port:" <<port << std::endl;
    io_service.run();
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }
  return 0;
}

回答1:


From a transport layer perspective, there is no different for UDP between a local network and the internet. However, there are various factors that can come into play:

  • UDP lacks reliability. Performing a single write and synchronously blocking waiting for a response will have good results on a LAN with minimal noise the majority of the time. However, it may be worth modifying the client to expect data loss when going across the internet. If the applications are going to need a high degree of reliability, then consider a different transport layer protocol, such as TCP.
  • If the server and client are on the same network, but the client is trying to connect to the server through the network's external IP, then verify that the gateway supports looping back internal traffic destined to the external IP.
  • Perform a traceroute to verify the IP packet's time to live field is higher enough for routing between the client and server.
  • Verify proper NAT support for routing devices between the client and server. RFC 4787 describes UDP and NAT requirements in detail. UDP Hole Punching may be required if the server is not actually publicly accessible.

In most cases, if the client and server work on a LAN, then it is often a networking issue. It may be worth debugging networking with basic tools like netcat and using reliable connection-based protocol, such as TCP. Once connectivity has been observed, then swap to using the UDP client and server.



来源:https://stackoverflow.com/questions/15993180/boost-c-udp-example-can-not-transmit-over-internet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!