UDP绑定:已在使用的地址

时间:2016-09-01 04:27:09

标签: c++ node.js udp boost-asio

我不了解node.js

我正在UDP发送C++个数据包,我希望在node.js中显示这些数据包。

问题是两者都试图占用IP /端口。根据我运行的那个,另一个失败。我该如何解决这个问题?

的main.cpp

// g++ main.cpp -o main -std=c++11 -lboost_system -pthread

#include <iostream>
#include <stdio.h>
#include <string>
#include <boost/asio.hpp>

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


int main(int argc, char* argv[])
{

    const int port=1414;
    const std::string ip="127.0.0.1";

    boost::asio::io_service io_service;
    udp::resolver resolver(io_service);

    udp::endpoint client_endpoint = *resolver.resolve({udp::v4(), ip, std::to_string(port)});
    udp::socket socket(io_service, udp::endpoint(udp::v4(), port));
    boost::asio::socket_base::reuse_address option(true);
    socket.set_option(option);

    std::string data;
    for(long i=0;true;i++)
    {
        data=std::to_string(i+1)+"th packet";
        socket.send_to(boost::asio::buffer(data.c_str(), data.length()+1), client_endpoint);
        usleep(10);
    }

    return 0;
}

app.js

var PORT = 1414;
var HOST = '127.0.0.1';

var dgram = require('dgram');
var server = dgram.createSocket('udp4');

server.on('listening', function () {
    var address = server.address();
    console.log('UDP Server listening on ' + address.address + ":" + address.port);
});

server.on('message', function (message, remote) {
    console.log(remote.address + ':' + remote.port +' - ' + message);

});

server.bind(PORT, HOST);

如果我运行C++文件然后运行js文件,则错误是:

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: bind EADDRINUSE 127.0.0.1:1414
    at Object.exports._errnoException (util.js:1012:11)
    at exports._exceptionWithHostPort (util.js:1035:20)
    at dgram.js:221:18
    at _combinedTickCallback (internal/process/next_tick.js:77:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
    at Module.runMain (module.js:577:11)
    at run (bootstrap_node.js:352:7)
    at startup (bootstrap_node.js:144:9)
    at bootstrap_node.js:467:3

然而,如果我首先运行js文件然后再运行C++文件,我会收到:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >'
  what():  bind: Address already in use
Aborted (core dumped)

2 个答案:

答案 0 :(得分:2)

@mscdex所写的内容是正确的,但@ EJP建议的是一种更为标准的方式来做你(我相信)试图完成的事情。

也就是说,您通常只有一个众所周知的端口上的服务器,例如1414,客户端通常在任何尚未使用的随机端口上启动。

为此,您不需要更改您的js代码,只需更改c ++代码的这一部分:

udp::endpoint client_endpoint
    = *resolver.resolve({udp::v4(), ip, std::to_string(port)});
udp::socket socket(io_service, udp::endpoint(udp::v4(), port));
boost::asio::socket_base::reuse_address option(true);
socket.set_option(option);

为:

udp::endpoint client_endpoint
    = *resolver.resolve({udp::v4(), ip, std::to_string(port)});
// Passing 0 as the port argument will tell the system to
// pick a random port for you.
udp::socket socket(io_service, udp::endpoint(udp::v4(), 0));

答案 1 :(得分:1)

创建套接字时需要设置reuseAddr: true

var server = dgram.createSocket({ type: 'udp4', reuseAddr: true });

您还需要更改在C ++端创建套接字的方式。目前,您正在使用的udp::socket构造函数签名将导致套接字立即绑定。不幸的是,您需要在绑定之前先设置reuse_address选项。要做到这一点,请尝试以下内容:

udp::socket socket(io_service, udp::v4());
socket.set_option(boost::asio::socket_base::reuse_address(true));
socket.bind(udp::endpoint(udp::v4(), port));