提升不通过网络工作

时间:2014-11-15 23:19:58

标签: c++ boost

我制作了一个简单的数据传输模块。我的大多数代码都基于我在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.

1 个答案:

答案 0 :(得分:0)

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

反过来,当客户端没有监听所需的接口时,可能会发生这种情况。

确保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 。请这样做;让你的代码自包含使人们能够真正解决问题