C++ Boost.ASIO: passing accepted TCP connection from one opened socket to another using Windows APIs ( while works with Linux APIs)?

青春壹個敷衍的年華 提交于 2019-12-09 01:21:30

问题


I was trying to learn how to re assign accepted connection using Boost.ASIO and Windows API's. found this code sample added to it includes and use of namespaces so now it is compilable - just copy and paste and here you go... "The parameter is incorrect" exception at the same place code poster had it=( So here is code:

#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();
}

In general code follows this post and I actually do not see what is wrong neither how to fix it.

And it follows way how we would pass accepted TCP connection from one process to another (described here)

May be this "Socket inheritance on different Windows platforms" example could help but I do not see how.

Can any one please help me to find any possible workaround that problem?


Update: Just tested code on Linux - works perfectly, no errors.

So what is it with windows version?


回答1:


Try using the code snippet attached to the WSASocket documentation:

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


Ok, I traced through the Boost code, and it fails trying to associate the socket with the I/O completion port. That's because the socket is already associated to a completion port.

The MSDN docs say:

It is best not to share a file handle associated with an I/O completion port by using either handle inheritance or a call to the DuplicateHandle function. Operations performed with such duplicate handles generate completion notifications. Careful consideration is advised.

Knowing that IOCP is related to the problem, I set (before including any boost headers)

#define BOOST_ASIO_DISABLE_IOCP 1

and everything works fine.

local output:

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

remote output:

I can use my duplicated socket via WinApi!
Not work


来源:https://stackoverflow.com/questions/5326564/c-boost-asio-passing-accepted-tcp-connection-from-one-opened-socket-to-anothe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!