使用boost asio指定ip和port创建一个iostream

时间:2010-11-25 08:32:36

标签: c++ client-server iostream boost-asio

我有关于增强asio库的问题。我成功地尝试在客户端和服务器之间创建套接字,这涉及创建解析器以指定服务器的ip和端口(服务器只需要端口)和其他对象,但是,最重要的是,有必要使用writeread_some作为从套接字读取和写入的函数。 我真的很感激使用一个流,这在boost asio中是可能的,但这很奇怪...... 在几乎所有使用流的例子中,创建服务器都需要提供端口,好吧,让我们来谈谈客户端...客户端,有必要使用iostream构造函数来指定连接流的坐标,这里是代码:

tcp::iostream() s(argv[1], "daytime");

好吧,我真的不明白第一个参数传递了什么,真的不知道白天可能代表什么... 基本上,在这里,我告诉:“嘿流,你必须连接到这个服务器...”但我怎么能指定该服务器的IP和端口? 请注意,相反,服务器端的一切都很清楚:

boost::asio::io_service io_s;
tcp::acceptor acc(io_s, tcp::endpoint(tcp::v4(), 1950));
for (;;) {
   tcp::iostream stream;
   acc.accept(*stream.rdbuf());
   stream << "Message" << std::endl;
}

使用此模型,我想使用

stream << mymessage_to_send << std::endl;
stream >> a_string_containing_my_message;

以便发送和接收。 我怎样才能做到这一点? 非常感谢你。

3 个答案:

答案 0 :(得分:18)

您引用的提升asio示例代码:

tcp::iostream s(argv[1], "daytime");

使用“daytime”作为服务表的查找(通常在linux系统上的/ etc / services中),这将识别日间服务的端口是13。

如果要连接到不是众所周知的服务之一的端口,可以使用以下内容进行连接:

tcp::iostream s("localhost", "57002"); 

请注意,端口号是作为字符串提供的,而不是作为无符号短整数提供的,因为可能会尝试尝试。

当然,“localhost”可以替换为IP地址“127.0.0.1”

答案 1 :(得分:1)

我使用Boost.Asio编写了一个客户端/服务器系统。该来源位于GitHubClient.cppServer.cpp。将Boost.Serialization与Boost.Asio一起使用可以让我通过线路发送任意数据结构。我必须说它令人印象深刻!

答案 2 :(得分:0)

让我们在这里解决所有3个问题:

在套接字客户端周围创建iostream

这很简单:

boost::asio::ip::tcp::iostream socketStream;
socketStream.connect( hostname, std::to_string( port ) );

您必须检查流的状态以查看它是否已成功连接。

在套接字服务器端创建iostream

假设你有你的接受者对象并且它受到约束和倾听......

boost::asio::ip::tcp::iostream connectionSocketStream; // from the connection object
acceptor.accept( *connectionSocketStream.rdbuf() );

//或

acceptor.async_accept( *connectionSocketStream.rdbuf(), callback );

其中callback是一个接收错误代码的函数。

流式传输

现在对于流式传输本身而言,问题在于,当您流出字符串“Message”时,客户端将需要知道此消息的开始和结束位置,并且常规iostream不会写任何内容来指定它。这真是iostream本身的一个缺陷。

因此答案是使用boost存档,只要您使用相同的两端,就可以使用文本或二进制存档。如果一方使用64位大端而另一方使用32位小端或任何其他混合,则无关紧要。

使用二进制存档,您将以这种方式发送消息:

boost::archive::binary_oarchive oarch( socketStream, boost::archive::no_header );
oarch << "Message";

请记住在此时完成发送所有要发送的内容后刷新流(socketStream,而不是oarch)。

并收到消息

boost::archive::binary_iarchive iarch( socketStream, boost::archive::no_header );
iarch >> message;

您可能会创建一个存档并在整个过程中使用它,尤其是对于出站。对于入站,如果您收到流式传输错误,可能会出现问题,因为它会破坏您的存档。

您可以使用文本存档而不是二进制存档。

boost存档将自动输入标题信息,以便它知道对象何时完成,并且只有在有完整对象或某些内容已损坏时才会返回给您。

注意:原始类型,例如std :: string甚至vector&lt; int&gt;存档自动处理等。您自己的类将需要特殊的重载,如何流式传输它们。你应该阅读boost :: archive文档。

注意:您可以在打开流之前将存档对象连接到流。存档围绕streambuf对象工作,该对象不会根据流成功打开而改变。

创建没有no_header会是一个问题,因为档案会立即尝试在构造中使用流(读取或写入其标题)