【问题标题】:Boost not working over networkBoost无法通过网络工作
【发布时间】:2014-11-15 23:19:57
【问题描述】:

我已经制作了一个简单的模块来传输数据。我的大部分代码都基于我在 SO 上找到的code

当我在本地机器上运行实例时,一切正常。但是如果我尝试在局域网上运行它,我会收到错误“无法分配请求的地址”。

注意:我的“实例基本上涉及运行 ./server 1 0 和 ./server 1 1 因此,它们正在等待数据。然后 ./server 0 将其发送过来。

这是代码

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/asio.hpp>

static std::string const server_ip = "10.0.0.4";
static std::string const client_ip = "10.0.0.5";

using std::cout;
using std::endl;

struct Location {
    double rent[6];
    double cost[7];
    std::string name, group;
    std::string locationOfObjectFile;
    int locationNo;

    template <typename Ar> void serialize(Ar &ar, unsigned) {
        ar &rent;
        ar &cost;
        ar &name;
        ar &group;
        ar &locationOfObjectFile;
        ar &locationNo;
    }
};

struct Player {
    int currentPosition;
    double currentMoney;

    template <typename Ar> void serialize(Ar &ar, unsigned) {
        ar &currentPosition;
        ar &currentMoney;
    }
};

struct Monopoly {
    std::vector<Location> locations;
    std::vector<Player> players;
    std::string currency;

    template <typename Ar> void serialize(Ar &ar, unsigned) {
        ar &locations;
        ar &players;
        ar &currency;
    }
};

Location l1;
Player p1;
Monopoly game, game2;

void readData(int x) {
    boost::asio::io_service io_service;
    uint16_t port = x;
    boost::asio::ip::tcp::acceptor acceptor(
        io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(server_ip), port));

    /* code */

    boost::asio::ip::tcp::socket socket(io_service);
    acceptor.accept(socket);
    std::cout << "connection from " << socket.remote_endpoint() << std::endl;

    // read header
    size_t header;
    boost::asio::read(socket, boost::asio::buffer(&header, sizeof(header)));
    std::cout << "body is " << header << " bytes" << std::endl;

    // read body
    boost::asio::streambuf buf;
    const size_t rc = boost::asio::read(socket, buf.prepare(header));
    buf.commit(header);
    std::cout << "read " << rc << " bytes" << std::endl;

    // deserialize
    std::istream is(&buf);
    boost::archive::text_iarchive ar(is);
    ar &game2;

    cout << game2.locations[0].rent[1] << endl;
    cout << game2.players[0].currentPosition << "how cool is this?";
    socket.close();
}

void sendData() {
    for (int i = 0; i <= 1; i++) {
        boost::asio::streambuf buf;
        std::ostream os(&buf);
        boost::archive::text_oarchive ar(os);
        ar &game;

        boost::asio::io_service io_service;
        boost::asio::ip::tcp::socket socket(io_service);
        short port = i + 1234;
        socket.connect(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(client_ip), port));

        const size_t header = buf.size();
        std::cout << "buffer size " << header << " bytes" << std::endl;

        // send header and buffer using scatter
        std::vector<boost::asio::const_buffer> buffers;
        buffers.push_back(boost::asio::buffer(&header, sizeof(header)));
        buffers.push_back(buf.data());
        const size_t rc = boost::asio::write(socket, buffers);
        std::cout << "wrote " << rc << " bytes" << std::endl;
        ;
        socket.close();
    }
}

int main(int argc, char **argv) {
    l1.name = "soemthig";
    l1.group = 2;
    p1.currentMoney = 300;
    p1.currentPosition = 422;
    for (int i = 0; i < 7; ++i) {
        l1.cost[i] = i;
        /* code */
    }
    for (int i = 0; i < 6; ++i) {
        l1.rent[i] = 2 * i;
        /* code */
    }
    l1.locationOfObjectFile = "ajhsdk/asdc.obj";
    l1.locationNo = 5;
    game.locations.push_back(l1);
    game.players.push_back(p1);
    game.currency = "dollar";
    cout << game.currency;
    if (atoi(argv[1]) ==
        1) // argv[0]=0 implies server, argv[0]==1 implies client while argv[1] specifies 1st or second client
    {
        cout << "reading data";

        if (atoi(argv[2]) == 0) {
            readData(1234);
            /* code */
        } else {
            readData(1235);
        }

    } else {
        cout << "writing data";
        sendData();
    }
}

这是错误消息堆栈跟踪:

libc++abi.dylib: terminating with uncaught exception of type boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector‌​<boost::system::system_error> >: bind: Can't assign requested address dollarreading dataAbort trap: 6 and 10.0.0.4 is the IP address of the computer that is supposed to send the data.

【问题讨论】:

  • 这是整个错误(这是一个运行时错误,所以没有行号) libc++abi.dylib: 以未捕获的 boost::exception_detail::clone_impl 类型异常终止<:exception_detail:: error_info_injector> >: bind: Can't assign requested address dollarreading dataAbort trap: 6 and 10.0.0.4 是应该发送数据的计算机的 IP 地址。
  • 看来你的IP地址10.0.0.4是你机器的。你不希望另一台机器的IP地址在那里吗?检查错误消息。我读错了吗?
  • 你读错了。引发错误的机器是 10.0.0.5。另一个是 10.0.0.4
  • 因为我没有使用这个功能,所以我需要更长的时间来解决这个问题。但我会认为你需要一些端口号来配合它。另外,不需要任何身份验证吗?另外,检查一下 - stackoverflow.com/questions/9882566/…
  • 我已将您的代码自包含并 running live on Coliru。请这样做;使您的代码自包含使人们可以实际解决问题。

标签: c++ boost


【解决方案1】:

当连接被拒绝时你会得到这个。

反过来,当客户端未在所需接口上侦听时,可能会发生这种情况。

确保 IP 地址实际上是网络上的公共 IP 地址,并且机器可以相互访问。例如。使用netstat -tlpn(或您的操作系统上的类似名称)来确定客户端正在监听:

tcp        0      0 192.168.2.136:1234      0.0.0.0:*               LISTEN      18186/valgrind.bin
tcp        0      0 192.168.2.136:1235      0.0.0.0:*               LISTEN      18187/valgrind.bin

现在,尝试使用例如连接来自服务器机器的 netcat:

netcat 192.168.2.136 1234

这可能会使客户端崩溃,但它也会告诉您是否可以连接。

如果不是,则地址不可访问,客户端未在正确的接口上侦听,防火墙正在过滤您的流量等。


PS。我已经让您的代码自包含并运行 live on Coliru。请这样做;使您的代码自包含使人们可以实际修复问题

【讨论】:

  • 我有一个问题。我打算将此功能放在 GLUT 显示功能中。默认情况下,boost 会使其异步工作吗?还是我必须更改我的代码?
猜你喜欢
  • 2012-04-01
  • 1970-01-01
  • 2016-07-16
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
  • 2019-07-30
  • 2013-04-03
  • 2017-08-23
相关资源
最近更新 更多