C ++ Boost.ASIO: передача принятого TCP-соединения из одного открытого сокета в другой с использованием API-интерфейсов Windows (в то время как работает с API-интерфейсами Linux)? - PullRequest
2 голосов
/ 16 марта 2011

Я пытался узнать, как переназначить принятое соединение, используя Boost.ASIO и Windows API.найдено этот пример кода добавлен к нему и включает в себя и использование пространств имен, так что теперь его можно скомпилировать - просто скопируйте и вставьте, и вот, пожалуйста ... Исключение «Параметр неверен» в том же месте, где был плакат с кодом= (Так вот код:

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

#ifdef _WIN32
#include "Windows.h"
#endif

using namespace boost::asio::ip;
using namespace std;

int main(){
int m_nPort = 12345;
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), m_nPort));

cout << "Waiting for connection..." << endl;

tcp::socket socket(io_service);
acceptor.accept(socket);
cout << "connection accepted" << endl;

#ifdef _WIN32
WSAPROTOCOL_INFO pi;
WSADuplicateSocket(socket.native(), GetCurrentProcessId(), &pi);
SOCKET socketDup = WSASocket(pi.iAddressFamily/*AF_INET*/, pi.iSocketType/*SOCK_STREAM*/,
                             pi.iProtocol/*IPPROTO_TCP*/, &pi, 0, 0);
char sText[] = "I can use my duplicated socket via WinApi!\r\n";
int nRet = send(socketDup, sText, strlen(sText), 0);
#else
//linux
 int socketDup = dup(socket.native()); // tested on Linux, works!
#endif

try
{
    tcp::socket s(io_service);
    s.assign(tcp::v4(), socketDup); //this throws exception under Windows
    //I can't use my socket via boost lib
    s.send(boost::asio::buffer("Not work\r\n"));
    cout << "We do not get here!=(" << endl;
}
catch(exception &e)
{
    cerr << e.what() << endl; //"The parameter is incorrect" exception
}
cin.get();
}

В общем * код 1006 * следует за этим постом , и я на самом деле не вижу, что не так, как это исправить.

Иэто следует из того, как мы передадим принятое TCP-соединение от одного процесса к другому ( описано здесь )

Может быть этот пример «наследования сокетов на разных платформах Windows» может помочь но я не понимаю, как.

Может ли кто-нибудь помочь мне найти возможное решение этой проблемы?


Обновление: Только что протестированный код в Linux- работает отлично, без ошибок.

Так что же с версией windows?

1 Ответ

4 голосов
/ 16 марта 2011

Попробуйте использовать фрагмент кода, прилагаемый к документации WSASocket:

socketDup = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &pi, 0, WSA_FLAG_OVERLAPPED);


Хорошо, я проследил через Boost-код ине удается связать сокет с портом завершения ввода-вывода.Это связано с тем, что сокет уже связан с портом завершения.

Документы MSDN говорят:

Лучше не использовать дескриптор файла, связанный сПорт завершения ввода / вывода с помощью дескриптора наследования или вызова функции DuplicateHandle.Операции, выполняемые с такими дублирующими дескрипторами, генерируют уведомления о завершении.Тщательное рассмотрение рекомендуется.

Зная, что IOCP связан с проблемой, я установил (перед включением любых заголовков повышения)

#define BOOST_ASIO_DISABLE_IOCP 1

и все работает нормально.

локальный выход:

Waiting for connection...
connection accepted
We do not get here!=(

удаленный выход:

I can use my duplicated socket via WinApi!
Not work
...