提升无法通过网络工作 [英] Boost not working over network

查看:53
本文介绍了提升无法通过网络工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

当我在本地计算机上运行实例时,一切正常.但是,如果我尝试通过局域网运行它,则会收到错误无法分配请求的地址".

注意:我的实例基本上涉及运行./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.

解决方案

当拒绝连接时,您会收到此消息.

这又可能在客户端未在所需接口上侦听时发生.

确保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.我已经使您的代码自成体系,并在Coliru上实时运行 >.请这样做;使您的代码自成一体,使人们可以实际修复问题

I've made a simple module for transferring data. Most of my code is based on code I found on SO

When I run the instances on my local machine, everything works fine. But if I try running this over a local area network, I get the error "Can't Assign Requested Address".

Note: My "instances basically involve running ./server 1 0 and ./server 1 1 so, they;re waiting for data. And then ./server 0 to send it over.

Here's the code

#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();
    }
}

Here is the error message stack trace:

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.

解决方案

You get this when the connection is refused.

This, in turn, could happen when the client is not listening on the required interface.

Make sure that the IP addresses are actually the public IP addresses on the network and the machines can reach eachother. E.g. use netstat -tlpn (or similar on your OS) to ascertain that the clients are listening:

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

Now, try to connect using e.g. netcat from the server machine:

netcat 192.168.2.136 1234

This will probably crash the client, but it will also tell you whether connecting was possible.

If not, then either the address is not reachable, the client is not listening on the right interface, the firewall is filtering your traffic etc.


PS. I've made your code self contained and running live on Coliru. Please do this; making your code selfcontained make it possible for people to actually fix things

这篇关于提升无法通过网络工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆