C ++ Boost.ASIO:使用Windows API(同时使用Linux API)将接受的TCP连接从一个打开的套接字传递到另一个?
我试图学习如何使用 Boost.ASIO 和 Windows API 重新分配接受的连接.发现 此代码示例 添加到其中包括和使用命名空间,所以现在是可编译 - 只需复制并粘贴即可...参数不正确"异常在同一个地方代码海报有它=(所以这里是代码:
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!
";
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
"));
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.
它遵循我们将接受的 TCP 连接从一个进程传递到另一个进程的方式(此处描述)
And it follows way how we would pass accepted TCP connection from one process to another (described here)
可能是这个不同Windows平台上的Socket继承"示例可能会有所帮助,但我不知道如何.
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?
更新:刚刚在 Linux 上测试过的代码 - 完美运行,没有错误.
Update: Just tested code on Linux - works perfectly, no errors.
那么windows版本是什么?
So what is it with windows version?
推荐答案
尝试使用 WSASocket
文档附带的代码片段:
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);
好的,我跟踪了 Boost 代码,但尝试将套接字与 I/O 完成端口关联失败.那是因为套接字已经与完成端口相关联.
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.
MSDN 文档说:
最好不要通过使用句柄继承或调用 DuplicateHandle 函数来共享与 I/O 完成端口关联的文件句柄.使用此类重复句柄执行的操作会生成完成通知.建议慎重考虑.
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.
知道 IOCP 与问题有关,我设置(在包含任何 boost headers 之前)
Knowing that IOCP is related to the problem, I set (before including any boost headers)
#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
相关文章