2016-01-04 2 views
0

Я работаю над многопроцессорным сервером сокета с библиотекой boost.boost asio SO_REUSEPORT

Каждый процесс запускает io_service.

Я хочу, чтобы все процессы принимались на одном и том же порту.

Я знаю SO_REUSEPORT (после ядра linux 3.9).

как этот питон скрипт

import socket                                      

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                            
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)                            

s.bind(('0.0.0.0', 9091)) 
s.listen(1) 

while True: 
    conn, addr = s.accept() 
    print "new connection" 
    while True: 
     data = conn.recv(100) 
     print "got data", data 
     if not data or data == 'exit': 
      break 
    conn.close() 

Но я не знаю, как использовать эту опцию в подталкивание ASIO io_service?

+0

Вы можете искать это. Это часто обсуждалось (с акцентом на то, когда использовать/правильно). В процессе вы можете увидеть различные способы установки порта повторного использования-addr/reuse-port. Некоторые из них зависят от платформы IIRC – sehe

+0

@sehe я искал в google, но не помог – Yueyoum

ответ

0

Ответа на этот вопрос.

#include <iostream> 
#include <string> 
#include <array> 
#include <boost/asio.hpp> 
#include <arpa/inet.h> 


using boost::asio::ip::tcp; 

int main() 
{ 
    boost::asio::io_service io; 
    tcp::acceptor acceptor(io); 
    acceptor.open(tcp::v4()); 

    int one = 1; 
    setsockopt(acceptor.native_handle(), SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &one, sizeof(one)); 

    acceptor.bind(tcp::endpoint(tcp::v4(), 9091)); 
    acceptor.listen(); 

    std::cout << "start" << std::endl; 
    for(;;) 
    { 
     tcp::socket socket(io); 

     acceptor.accept(socket); 
     std::cout << "new connections" << std::endl; 
     for(;;) 
     {                                        
      std::array<char, 4> buf; 
      boost::system::error_code error; 
      boost::asio::read(socket, boost::asio::buffer(buf), error); 
      if(error) 
      { 
       std::cout << "read error: " << error << std::endl; 
       break; 
      } 
      std::cout << "read: " << std::string(buf.data()) << std::endl; 
     } 
    } 
} 
+1

Вы должны включить более подробное описание того, что вы изменили, чтобы заставить его работать вместо блока кода и слова «Отвечайте сами». –

1

Пример HTTP-сервер показывает один из способов: http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp11/http/server/server.cpp

// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). 
    boost::asio::ip::tcp::resolver resolver(io_service_); 
    boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve({address, port}); 
    acceptor_.open(endpoint.protocol()); 
    acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); 
    acceptor_.bind(endpoint); 
    acceptor_.listen(); 

IIRC есть также acceptor конструктор, который принимает логическое значение, чтобы установить флаг повторного использования.

+4

Мне нужно, REUSE_PORT, а не REUSE_ADDRESS – Yueyoum

1

Следуя от того, как повышение/ASIO/socket_base.hpp определяет reuse_address, я сделал это так:

typedef boost::asio::detail::socket_option::boolean<SOL_SOCKET, SO_REUSEPORT> reuse_port; 
socket_.set_option(reuse_port(true));