如何在Boost.ASIO中分配已连接的本地套接字类型(TCP)

3
有没有一种方法可以在ASIO中使用已经连接的套接字?
尝试发送一个请求时,ip::tcp::socket::assign会在两个不同的位置随机出现2个不同的段错误。其中一个是在调用回调之前(在op_queue_acess::next上),另一个是在回调之后(在boost::asio::detail::task_io_service_operation::complete上(func_等于0并试图被执行))。所以我猜它不能与已连接的套接字一起使用。
编辑:
情况是,我有一个已连接的本地描述符(实际上是另一个库下面的套接字),我想将其分配给一个新的、空的ip::tcp::socket,这样当套接字准备好读取(使用带有空缓冲区的socket::async_read_some)时,我就能收到通知,并以非阻塞方式使用该库。
示例代码如下:
class C
{
 ip::tcp::socket socket_;
 const char connection_info_[] = "...";
 TPLibrary tp_;

 void start()
 {
  .
  .
  tp_.connect(connection_info);
  socket_.assign(ip::tcp::v4(), tp_.nativeSocket());
 }
}

在这个套接字上使用async_read会导致所述的段错误,有时是在调用回调之后,有时是之前。

编辑: 现在我已经删除了所有内容,只剩下tcp::socket和分配给套接字,但仍然会出现boost崩溃。这是因为io_service位于一个动态加载库中,而socket位于另一个动态加载库中,并且具有对主库上io_service的引用吗?


你的问题不够清晰。你想要将一个已连接的 boost::asio::ip::tcp::socket 分配给一个已存在的本地描述符吗? - Sam Miller
Asio文档中包含了一个展示反应器风格操作的示例。在Stack Overflow上也有类似的问题。请在您的问题中包含您的代码,以便我们提供帮助。 - Sam Miller
@SamMiller 在该示例中,第三方库也使用了ip::tcp::socket。我无法修改该库以使用ip::tcp::socket。该库使用本机方法进行所有连接操作,并提供了设置阻塞状态和获取fd的函数选项。除了在调用library_connect()方法时连接到服务器之外,我不知道该库还做了什么其他操作,所以我必须找到一种方法将已连接的socket传入asio循环中。 - Etherealone
这个例子只是一个例子,它并不打算涵盖每个第三方库。空缓冲区的概念是为了解决你的问题而设计的。请编辑你的问题,包括演示你问题的代码。 - Sam Miller
@sammiller 我已经添加了一个例子。 - Etherealone
让我们在聊天室继续这个讨论 - Sam Miller
2个回答

1
你可以将已连接的套接字分配给boost::asio套接字,并从那时起享受boost功能。
从下面的链接中,您可以找到如何使用assign API。

http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_stream_socket/assign/overload1.html

如果您有任何问题,请告诉我。

编辑:

现在,如果你的问题是关于非阻塞读取,因为async_read_some是非阻塞的,那么可以使用read_some如下所示:

boost::asio::async_read(*p_socket, boost::asio::buffer(&buffer[index], remaining_len2read), read_handler);

上述API是阻塞的,直到所有数据接收完毕才会返回。

我用过它,当我使用ASIO函数时会出现段错误。我认为'ASIO connect'的作用不仅仅是连接,而且assign函数做得不够,这是真的吗? - Etherealone
这是不正确的,原帖想要使用null_buffers并让库来处理从本地套接字读取数据。 - Sam Miller
你(@Tolga)使用null_buffers有特定的原因吗? - Chirag Desai
@ChiragDesai 是的,这个库应该读取并处理数据。 - Etherealone

1
这个问题与我使用的动态链接有关。作为回答,tcp::socket::assign 在连接的套接字上运行良好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接