简体   繁体   English

C ++ Boost.ASIO:使用Windows API将可接受的TCP连接从一个打开的套接字传递到另一个(与Linux API一起使用)吗?

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

I was trying to learn how to re assign accepted connection using Boost.ASIO and Windows API's. 我正在尝试学习如何使用Boost.ASIO和Windows API重新分配接受的连接。 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 ) 它遵循以下方式:如何将接受的TCP连接从一个进程传递到另一个进程( 在此处描述

May be this "Socket inheritance on different Windows platforms" example could help but I do not see how. 可能是这个“在不同Windows平台上的套接字继承”示例可能有帮助,但我不知道如何。

Can any one please help me to find any possible workaround that problem? 任何人都可以帮助我找到该问题的任何可能的解决方法吗?


Update: Just tested code on Linux - works perfectly, no errors. 更新:刚刚在Linux上测试过的代码-完美运行,没有错误。

So what is it with windows version? 那么Windows版本是什么呢?

Try using the code snippet attached to the WSASocket documentation: 尝试使用 WSASocket文档附带的代码段:

 
 
 
  
  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. 好的,我跟踪了Boost代码,但是尝试将套接字与I / O完成端口关联失败。 That's because the socket is already associated to a completion port. 这是因为套接字已经与完成端口关联。

The MSDN docs say: MSDN文档说:

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. 最好不要通过句柄继承或对DuplicateHandle函数的调用来共享与I / O完成端口关联的文件句柄。 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) 知道IOCP与问题有关,我进行了设置(在包含所有boost头之前)

#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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM