如何使用specfic的NetworkInterface / IP与升压短耳插座? [英] How to use a specfic Networkinterface/Ip with Boost Asio sockets?

查看:236
本文介绍了如何使用specfic的NetworkInterface / IP与升压短耳插座?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有哪几种叶一个Debian / Linux服务器不会忽略,都分配到同一个物理网卡。在的/ etc /网络/接口配置文件看起来像这样(XX的重present号)

I have a Debian/linux server which has several Ip adresses, all assigned to the same physical network card. The /etc/network/interfaces config file looks like this (the xx represent numbers)

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 176.xx.xx.144
    netmask 255.255.255.0
    network 176.xx.xx.0
    broadcast 176.xx.xx.255
    gateway 176.xx.xx.254

auto eth0:0
allow-hotplug eth0:0
iface eth0:0 inet static
    address 46.xx.xx.57
    netmask 255.255.255.255
    broadcast 46.xx.xx.57

auto eth0:1
allow-hotplug eth0:1
iface eth0:1 inet static
    address 94.xx.xx.166
    netmask 255.255.255.255
    broadcast 94.xx.xx.166

//IPv6 Stuff...

我的工作,使用升压短耳处理所有的网络连接客户端应用程序。在这个应用我想能够连接到使用特定的NetworkInterface / IP地址的外部服务器。我发现这个的类似的问题,但只是绑定的boost ::支持ASIO ::知识产权:: TCP ::插座来一个specfic端点,然后连接到外部服务器无法正常工作。这里是什么我想一个最小的例子:

I am working on a client application that uses Boost Asio to handle all network connections. In this Application I want to be able to connect to an external server using a specific networkinterface/Ip address. I found this similar question, however simply binding a boost::asio::ip::tcp::socket to a specfic endpoint and then connect to an external Server doesn't work. Here is a minimal working example of what I tried:

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

int main( int argC, char *argV[] ) {
    boost::asio::io_service ioService;
    boost::asio::ip::tcp::socket socket(ioService);

    boost::asio::ip::tcp::endpoint localEndpoint(
        boost::asio::ip::address::from_string("94.xx.xx.166"), 0);

    boost::asio::ip::tcp::resolver resolver(ioService);
    boost::asio::ip::tcp::resolver::iterator remoteEndpoint = 
        resolver.resolve(boost::asio::ip::tcp::resolver::query("haatschii.de", "80"));

    socket.open(boost::asio::ip::tcp::v4());

    std::cout   << "Before binding socket has local endpoint: " 
                << socket.local_endpoint().address().to_string() 
                << ":" << socket.local_endpoint().port() << std::endl;

    socket.bind(localEndpoint);

    std::cout   << "Before connecting socket has local endpoint: " 
                << socket.local_endpoint().address().to_string() 
                << ":" << socket.local_endpoint().port() << std::endl;

    boost::asio::connect(socket, remoteEndpoint);

    std::cout   << "After connecting socket has local endpoint: " 
                << socket.local_endpoint().address().to_string() 
                << ":" << socket.local_endpoint().port() << std::endl;

    //Test request to a page that echos our IP address.
    boost::asio::write(socket, 
        boost::asio::buffer("GET /ip.php HTTP/1.1\r\nHost: haatschii.de\r\nAccept: */*\r\n\r\n", 57));

    //Parse server response (not important for this code example)
    return 0;
}

当我在我的服务器上运行此我得到:

When I run this on my server I get:

Before binding socket has local endpoint: 0.0.0.0:0
Before connecting socket has local endpoint: 94.xx.xx.166:38399
After connecting socket has local endpoint: 176.xx.xx.144:45959
External server says we are using IP: 176.xx.xx.144

现在我有点失落,因为我不知道还有什么尝试。我并不需要为这个便携式解决方案,任何与此Debian的安装程序会做工作。

Right now I am a bit lost, because I don't know what else to try. I don't necessarily need a portable solution for this, anything that works with this Debian setup will do.

我会提供,对于我的设置工作的解决方案赏金。如果有必要,我可以修改的/ etc /网络/接口配置文件。不过,为了重用我的code,任何解决方案具有升压短耳插座(至少一个包装)的工作。

I'll offer the bounty for a solution that works for my setup. If necessary I can change the /etc/network/interfaces config file. However in order to reuse my code, any solution has to work with Boost Asio sockets (at least as a wrapper).

推荐答案

要绑定到你必须首先打开连接特定的接口。你这样做 - 到目前为止好。但在那之后你叫的boost :: ASIO ::连接(插座,remoteEndpoint); 这将关闭作为您的连接(作为一个服务说了)。

To bind to a specific interface you have to open the connection first. You do that - so far so good. But after that you call boost::asio::connect(socket, remoteEndpoint); which will close the connection for you (as a service so to say).

升压告诉你,它这样做 - 但你必须仔细观察。在根据参数为参考的重载版本连接您使用的是它会说

Boost tells you that it does so - but you have to look closely. In the reference under parameters for the overloaded version of connect you are using it will say

参数

取值

插座进行连接。如果套接字已打开,它将被关闭。

The socket to be connected. If the socket is already open, it will be closed.

或在其推动实施/ ASIO / IMPL / connect.hpp:

or in its implementation in boost/asio/impl/connect.hpp:

// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

[...]

template <typename Protocol, typename SocketService,
    typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol, SocketService>& s,
    Iterator begin, Iterator end, ConnectCondition connect_condition,
    boost::system::error_code& ec)
{
  ec = boost::system::error_code();

  for (Iterator iter = begin; iter != end; ++iter)
  {
    iter = connect_condition(ec, iter);
    if (iter != end)
    {
      s.close(ec);
      s.connect(*iter, ec);
      if (!ec)
        return iter;
    }
  }

  if (!ec)
    ec = boost::asio::error::not_found;

  return end;
}

(注意 S.CLOSE(EC);

解决方案

应该很简单。替换的boost ::支持ASIO ::连接...

socket.connect(*remoteEndpoint);

(或一个循环在相应的远程端点,类似于升压源$ C ​​$ C,如果需要的话)。

(or a loop over the respective remote endpoints, similar to the boost sourcecode, if necessary.)

这篇关于如何使用specfic的NetworkInterface / IP与升压短耳插座?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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