2016-05-27 2 views
1

Итак, у меня есть сервер TCP, который ждет определенного порта для подключения клиентов.Boost :: ASIO: использование tcp :: socket на несколько потоков

Если есть одно соединение с клиентом, я создаю объект tcp::socket с некоторыми asio::io_service, а затем принимаю этот сокет. Пример:

void Gateway::server(boost::asio::io_service& io_service, unsigned short port) { 
    tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port)); 
    bool UARTToWiFiGatewayStarted = false; 

    for (;;) { 
     tcp::socket sock(io_service); 

     a.accept(sock); 

     std::thread(startWiFiToUARTSession, std::move(sock)).detach(); 

     if(false == UARTToWiFiGatewayStarted) { 
      //std::thread(startUARTToWifiSession, std::move(sock2)).detach(); 
      UARTToWiFiGatewayStarted = true; 
     } 
    } 
} 

Теперь я хочу использовать функциональные возможности этого сокета, по меньшей мере, двух потоков, один поток будет читать (блокировка) из гнезда (read_some(...)), а другой поток должен писать (блокирование) данных с использованием, что разъем.

Я пытался построить два объекта tcp::socket, используя тот же объект asio::io_service, но это не сработает.

Любые идеи?

+1

Что вы подразумеваете под «не будет работать»? – Xirema

+0

«использовать функциональность этого сокета, по крайней мере, для двух потоков» - вы имеете в виду это же соединение с одним клиентом? –

+1

Каждый объект 'tcp :: socket' должен ссылаться на дискретный родной сокет. Можете ли вы объяснить мотивацию желания использовать два объекта 'tcp :: socket' для одного TCP-соединения? –

ответ

2

Объект socket предназначен для владения родным сокетом и предоставляет семантику для управления родным сокетом RAII. Следовательно, отдельные объекты socket должны относиться к дискретным родным сокетам. В противном случае состояние основного сокета может неожиданно измениться.

В то время как документация socket указывает, что одновременные вызовы на одном общем socket небезопасны, revision history документирует исключение из этого правила. По Asio 1.4.0/Повышение 1.37, если поддерживается ОС, синхронного чтения, записи, принимать и операции соединения, которые производятся одновременно на socket объекта являются поточно:

Asio 1.4. 0/Повысьте 1,37

  • ...
  • Синхронное чтение, запись, принимать и соединить операции теперь Потокобезопасная (это означает, что теперь разрешается выполнять одновременно синхронные операции на индивидуальной розеткой, если эта функция поддерживается ОС).
  • ...

В этом случае, если поддерживается ОС, это поточно синхронно читать из сокета в одном потоке, и синхронно записывать в тот же сокет одновременно в другом потоке.