|
Boost Users : |
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2019-12-21 14:40:33
The socket interface has the release() method which disassociates the
native handle from the asio socket object.
There is a constructor overload which takes a native handle.
No need for dup() or equivalent.
R
On Fri, 20 Dec 2019 at 11:36, Klebsch, Mario via Boost-users <
boost-users_at_[hidden]> wrote:
> Hello,
>
>
>
> I am using boost asio in a cross platform project. The project consists of
> two libraries, having a C call API in between.
>
>
>
> Until now, each of those two libraries uses boost::asio internally. Each
> of these libraries have their own instance of boost::asio::io_service.
>
>
>
> I now need to implement a change, that requires to pass a connected socket
> from one library to the other one via the C call API:
>
>
>
> This is what I want to do it.
>
>
>
> * Lib1 calls new method connect() in lib2
>
> * lib2::connect() creates a boost::asio::ip::tcp::socket
>
> * lib2::connect() connects to a service
>
> * lib2::connect() does some async communication with that service.
>
> * when the service is initialized, lib2::connect() shall
>
> pass the native handle back to its caller (Lib1).
>
> * Lib1 then creates a boost::asio::ip::tcp::socket from the native handle
>
>
>
> I have learned, that there is no way to destroy a
> boost::asio::ip::tcp::socket without closing the native handle.
>
>
>
> So, I have to dup() it. No problem on POSIX systems, on Windows I can use
> a combination of WSADuplicateSocket () and WSASocket () to achieve the
> same.
>
>
>
> Everything works fine on Linux, but on Windows, the parts do not work
> together J
>
>
>
> The individual parts are working find.
>
> * I can use the boost::asio::ip::tcp::socket to communicate with the
> service.
>
> * I can use WSADuplicateSocket () and WSASocket () to get a 2nd, native
> handle to the socket
>
> * I can use the 2nd, native handle to communicate to the service, even
> after destroying the boost::asio::ip::tcp::socket instance.
>
> * I also can create a working boost::asio::ip::tcp::socket from a native
> socket handle, created with socket() and connected to a service with
> connect().
>
>
>
> BUT: If I try to create a boost::asio::ip::tcp::socket on the socket
> created by the WSADuplicateSocket () and WSASocket () sequence, I get an
> exception.
>
>
>
> The call to CreateIoCompletionPort() in win_iocp_io_service.ipp,
> win_iocp_io_service::register_handle() fails with error 87 (Invalid
> Parameter).
>
>
>
> I have no idea, why CreateIoCompletionPort() is failing and how to avoid
> this.
>
>
>
> Here is a sample program demonstrating my problem. If BUG is #defined, the
> code fails with std::exception âassign: Falscher Parameterâ (invalid
> parameter).
>
>
>
> #ifdef _WIN32
>
> #include <winsock2.h>
>
> #include <ws2tcpip.h>
>
> #else
>
> #include <sys/socket.h>
>
> #endif
>
>
>
> #include <boost/asio.hpp>
>
>
>
> #define ADDR "127.0.0.1"
>
> #define PORT "7" /* echo */
>
>
>
> #include <stdio.h>
>
>
>
> #ifndef _WIN32
>
> inline int WSAGetLastError() { return errno; }
>
> #endif
>
>
>
> int main()
>
> {
>
> char Request[]="Hello";
>
> char Buffer[256];
>
> int n;
>
>
>
> try
>
> {
>
> #ifdef _WIN32
>
> SOCKET s1 = INVALID_SOCKET;
>
> #else
>
> int s1=-1;
>
> #endif
>
> #ifdef BUG
>
> {
>
> printf("The programm does not work with this code on
> windows :-(\n");
>
> boost::asio::io_service IoService;
>
> boost::asio::ip::tcp::resolver Resolver(IoService);
>
> boost::asio::ip::tcp::resolver::query Query(ADDR,
> PORT);
>
> boost::asio::ip::tcp::socket s(IoService);
>
> s.connect(*Resolver.resolve(Query));
>
> printf("connected\n");
>
>
>
> #ifdef _WIN32
>
> WSAPROTOCOL_INFO ProtocolInfo;
>
> DWORD MyProcId = GetCurrentProcessId();
>
> int x = WSADuplicateSocket((SOCKET)s.native_handle(),
> MyProcId, &ProtocolInfo);
>
> if (x)
>
> throw
> boost::system::error_code(WSAGetLastError(),
> boost::system::system_category());
>
>
>
> s1 = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
> FROM_PROTOCOL_INFO, &ProtocolInfo, 0, WSA_FLAG_OVERLAPPED);
>
> #else /* !_WIN32 */
>
> s1=dup(s.native_handle());
>
> #endif /* !_WIN32 */
>
> if (s1<0)
>
> throw
> boost::system::error_code(WSAGetLastError(),
> boost::system::system_category());
>
> }
>
> #else
>
> s1 = socket(PF_INET, SOCK_STREAM, 0);
>
> if (s1 < 0)
>
> throw boost::system::error_code(WSAGetLastError(),
> boost::system::system_category());
>
> struct sockaddr_in Addr;
>
> Addr.sin_family = AF_INET;
>
> Addr.sin_port = htons(atoi(PORT));
>
> inet_pton(AF_INET, ADDR, &Addr.sin_addr);
>
> if (connect(s1, (struct sockaddr*)&Addr, sizeof(Addr)) < 0)
>
> throw boost::system::error_code(WSAGetLastError(),
> boost::system::system_category());
>
> #endif
>
> printf("s1=%d\n", s1);
>
> {
>
> boost::asio::io_service IoService;
>
> boost::asio::ip::tcp::socket s(IoService,
> boost::asio::ip::tcp::v4(),
> (boost::asio::ip::tcp::socket::native_handle_type)s1);
>
> n = s.write_some(boost::asio::buffer(&Request, sizeof
> (Request)));
>
> printf("write_some() returned %d\n", n);
>
> n = s.read_some(boost::asio::buffer(Buffer, sizeof
> (Buffer)));
>
> printf("read_some() returned %d\n", n);
>
>
>
> }
>
> return 0;
>
> }
>
> catch (boost::system::error_code &ec)
>
> {
>
> fprintf(stderr, "boost::system::error_code: %s\n",
> ec.message().c_str());
>
> return -1;
>
> }
>
> catch (std::exception &e)
>
> {
>
> fprintf(stderr, "std::exception: %s\n", e.what());
>
> return -1;
>
> }
>
> }
>
>
>
> Thanks in advance,
>
>
>
> Mario
>
> --
>
> Mario Klebsch Actia I+ME GmbH
>
> Mario.klebsch_at_[hidden] Dresdenstrasse 17/18
> <https://www.google.com/maps/search/Dresdenstrasse+17%2F18?entry=gmail&source=g>
> Fon: +49 531 38 701 716 38124 Braunschweig
> Fax: +49 531 38 701 88 German
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users
>
-- Richard Hodges hodges.r_at_[hidden] office: +442032898513 home: +376841522 mobile: +376380212
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net