2010-11-25 101 views
6

我有一个关于boost asio库的问题。我成功尝试在客户端和服务器之间创建一个套接字,这涉及到创建解析器以便指定服务器的ip和端口(服务器只需要端口)和其他对象,但是,最重要的是,必须使用writeread_some作为从套接字读取和写入的函数。 我真的很喜欢使用流,这是可能的升压asio,但这很奇怪... 在几乎所有使用流的例子中,创建一个服务器,有必要提供端口,好的,让我们来谈谈客户端......客户端,它是需要使用的iostream构造函数用于连接流指定坐标,下面的代码:使用boost asio指定ip和port创建一个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; 

。 我该怎么做? 非常感谢。

回答

1

我已经使用Boost.Asio编写了客户机/服务器系统。该来源可在GitHubClient.cppServer.cpp。使用Boost.Serialization和Boost.Asio一起使我可以通过电线发送任意数据结构。我必须说这是相当令人印象深刻的!

+0

OK,要立即检查一下......谢谢 – Andry 2010-11-25 09:02:41

+0

你如果你愿意,可以自由地问我关于我的实施的问题。祝你好运! – 2010-11-25 09:07:47

17

升压ASIO示例代码你报:

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

使用“白天”作为查找到服务表(通常在Linux系统的/ etc/services中),这将确定该端口白天服务是13

如果你想连接到一个端口,是不是众所周知的服务之一,你可以像这样做:

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

注日在端口号是作为一个字符串提供,而不是一个无符号的短整数,因为人们可能会试图尝试。

创建围绕插座客户端了iostream:

当然, “localhost” 的可以用一个IP地址 “127.0.0.1”

0

让我们解决所有的3个问题在这里所取代。

这是非常简单的:

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); 

,其中回调是一个函数,一个错误代码。

流对象

现在的流媒体本身,在这里你的问题是,当你流出来的字符串“消息”客户端需要知道这个消息的开始和结束,以及定期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,甚至是矢量< int>等会自动由归档处理。您自己的课程将需要特殊的重载,以便如何流式传输它们。你应该阅读boost :: archive文档。

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

创建不no_header将是一个问题,虽然作为档案立即尝试使用建筑流(读取或写入它们的头)

相关问题