我需要创建进程并将连接的套接字传递给新创建的进程,并且在新进程中将对套接字进行进一步的操作。我使用了以下代码。一切正常,但是当我在完成工作后尝试关闭子进程时,它会在该行引发访问冲突,
return InterlockedCompareExchangePointer(dest, exch, cmp);
文件" win_iocp_socket_service_base.ipp"中的,位于路径" boost \ asio \ detail \ impl"
以下是我的代码。
#include <iostream>
#include <tchar.h>
#define BOOST_ASIO_DISABLE_IOCP 1
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time.hpp>
#ifdef _WIN32
#include "Windows.h"
#endif
#include <string>
using namespace boost::asio::ip;
using namespace std;
int main(int argc, char* argv[]){
cout << "Current Process Id...." << GetCurrentProcessId() << endl;
cout << "Argument count..." << argc << endl;
if (3 == argc){
boost::this_thread::sleep(boost::posix_time::seconds(15));
ostringstream ss;
ss << argv[2];
if (ss.str() == "CHILD"){
cout << "Message To child...." << ss.str() << endl;
try
{
SOCKET Sock;
if (2 < argc){
Sock = atoi(argv[1]); // use Sock
}
boost::asio::io_service io_service2;
tcp::socket s(io_service2);
s.assign(tcp::v4(), Sock);
s.send(boost::asio::buffer("Message to client\r\n"));
s.close();
return 0;
}
catch (exception &e)
{
cerr << e.what() << endl; //"The parameter is incorrect" exception
}
return 0;
}
}
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);
#else
//linux
int socketDup = dup(socket.native()); // tested on Linux, works!
#endif
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
TCHAR argbuf[256];
memset(&si, 0, sizeof(si));
wsprintf(argbuf, _T("Server.exe %d %s"), socketDup, _T("\"CHILD\""));
if (!CreateProcess(NULL, argbuf, NULL, NULL,
TRUE, // inherit handles
0, NULL, NULL, &si, &pi)){
fprintf(stderr, "createprocess failed %d\n", GetLastError());
return -1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
}
socket.close();
cin.get();
}
我发现错误是由"#define BOOST_ASIO_DISABLE_IOCP 1"
但是没有这个,我不能在这一行复制套接字s.assign(tcp::v4(), Sock);
我怎么能解决这个问题,请帮助我。
答案 0 :(得分:0)
我误解了这是因为从'线程'复制套接字而不是“进程”视力不佳。 WSADuplicateSocket函数是正确的。然而,需要注意的是底层套接字将保持打开状态,直到此套接字的所有描述符都被释放,包括父代。 WSADuplicate
直接来自MSDN:
进程可以在重复的套接字上调用closesocket 描述符将被取消分配。但是,底层套接字 将保持打开状态,直到最后剩余的人员调用closesocket 描述符。
答案 1 :(得分:0)
最后我得到了解决方案。
1.评论该行
#define BOOST_ASIO_DISABLE_IOCP 1
2.将套接字更改为共享指针。 - 谢谢你@Samer Tufail的共享指针建议
我的工作代码。
#include <iostream>
#include <tchar.h>
#include <boost/thread/thread.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time.hpp>
#ifdef _WIN32
#include "Windows.h"
#endif
#include <string>
using namespace boost::asio::ip;
using namespace std;
int main(int argc, char* argv[]){
cout << "Current Process Id...." << GetCurrentProcessId() << endl;
cout << "Argument count..." << argc << endl;
if (3 == argc){
boost::this_thread::sleep(boost::posix_time::seconds(15));
ostringstream ss;
ss << argv[2];
if (ss.str() == "CHILD"){
cout << "Message To child...." << ss.str() << endl;
try
{
SOCKET Sock;
if (2 < argc){
Sock = atoi(argv[1]); // use Sock
}
boost::asio::io_service io_service2;
tcp::socket s(io_service2);
io_service2.run();
s.assign(tcp::v4(), Sock);
s.send(boost::asio::buffer("Message to client\r\n"));
s.close();
return 0;
}
catch (exception &e)
{
cerr << e.what() << endl;
}
return 0;
}
}
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;
boost::shared_ptr<tcp::socket> socket(new tcp::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);
#else
//linux
int socketDup = dup(socket.native()); // tested on Linux, works!
#endif
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
TCHAR argbuf[256];
memset(&si, 0, sizeof(si));
wsprintf(argbuf, _T("Server.exe %d %s"), socketDup, _T("\"CHILD\""));
if (!CreateProcess(NULL, argbuf, NULL, NULL,
TRUE, // inherit handles
0, NULL, NULL, &si, &pi)){
fprintf(stderr, "createprocess failed %d\n", GetLastError());
return -1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
}
cin.get();
}