Boost.Asio翻译(三)琐碎集

ThistutorialprogramshowshowtouseasiotoimplementaclientapplicationwithTCP.

Westartbyincludingthenecessaryheaderfiles.

本示例程序显示如何使用Asio来实现一个TCP客户端程序。

让我们从添加必需的头文件开始。

这个应用程序的目的是访问一个daytime服务器,因此我们需要用户去指定服务器。(如time-nw.nist.gov,用IP亦可)

usingboost::asio::ip::tcp;intmain(intargc,char*argv[]){try{if(argc!=2){std::cerr<<"Usage:client"<

所有使用asio的程序都至少需要一个boost::asio::io_service对象。

我们需要把服务器的名称转化为TCP的节点,而该名称是通过应用程序的参数指定的。我们使用boost::asio::ip::tcp::resolver对象来完成。

一个resolver对象获得一个query对象,并将其转换为节点列表.我们通过argv[1]中的服务器名称和服务名,在这里是daytime,构造一个query。

节点列表用boost::asio::ip::tcp::resolver::iterator类型的迭代器返回。返回的iterator将采用boost::asio::ip::tcp::resolver::iterator的默认构造函数来构造。

tcp::resolver::iteratorendpoint_iterator=resolver.resolve(query);tcp::resolver::iteratorend;Nowwecreateandconnectthesocket.ThelistofendpointsobtainedabovemaycontainbothIPv4andIPv6endpoints,soweneedtotryeachofthemuntilwefindonethatworks.ThiskeepstheclientprogramindependentofaspecificIPversion.

现在我们建立一个socket并连接之,由于获得的节点既有IPv4也有IPv6的。所以,我们需要依次尝试访问它们直到找到一个可以正常工作的。这样做可使得我们的程序独立于特定的IP版本。

tcp::socketsocket(io_service);boost::system::error_codeerror=boost::asio::error::host_not_found;while(error&&endpoint_iterator!=end){socket.close();socket.connect(*endpoint_iterator++,error);}if(error)throwboost::system::system_error(error);Theconnectionisopen.Allweneedtodonowisreadtheresponsefromthedaytimeservice.

Weuseaboost::arraytoholdthereceiveddata.Theboost::asio::buffer()functionautomaticallydeterminesthesizeofthearraytohelppreventbufferoverruns.Insteadofaboost::array,wecouldhaveusedachar[]orstd::vector.

连接打开后,现在我们需要做的就是读取daytime服务器的响应。

我们使用boost::array来存放接收到的数据。boost::asio::buffer()函数会自动确定array的长度来防止缓冲区溢出。我们也可以使用char[]或std::vector来代替boost::array。

for(;;){boost::arraybuf;boost::system::error_codeerror;size_tlen=socket.read_some(boost::asio::buffer(buf),error);Whentheserverclosestheconnection,theboost::asio::ip::tcp::socket::read_some()functionwillexitwiththeboost::asio::error::eoferror,whichishowweknowtoexittheloop.

当服务器关闭连接时,boost::asio::ip::tcp::socket::read_some()函数会以boost::asio::error::eof错误标志返回,通过该错误标志,我们知道应该退出循环了。

if(error==boost::asio::error::eof)break;//Connectionclosedcleanlybypeer.elseif(error)throwboost::system::system_error(error);//Someothererror.std::cout.write(buf.data(),len);}Finally,handleanyexceptionsthatmayhavebeenthrown.

最后,处理所有可能抛出的异常。

完整代码:

一个同步的TCPdaytime服务器

ThistutorialprogramshowshowtouseasiotoimplementaserverapplicationwithTCP.

本示例示范如何使用Asio来实现一个TCP服务器程序。

我们先定义一个make_daytime_string()来产生需要发送给客户端的字符串.这个函数会在我们所有的daytime服务器上被使用。

std::stringmake_daytime_string(){usingnamespacestd;//Fortime_t,timeandctime;time_tnow=time(0);returnctime(&now);}intmain(){try{boost::asio::io_serviceio_service;Aboost::asio::ip::tcp::acceptorobjectneedstobecreatedtolistenfornewconnections.ItisinitialisedtolistenonTCPport13,forIPversion4.

新建一个asio::ip::tcp::acceptor对象来监听新的连接。该对象应遵守IPv4协议,监听TCP端口13。

Thisisaniterativeserver,whichmeansthatitwillhandleoneconnectionatatime.Createasocketthatwillrepresenttheconnectiontotheclient,andthenwaitforaconnection.

for(;;){tcp::socketsocket(io_service);acceptor.accept(socket);Aclientisaccessingourservice.Determinethecurrenttimeandtransferthisinformationtotheclient.

std::stringmessage=make_daytime_string();boost::system::error_codeignored_error;boost::asio::write(socket,boost::asio::buffer(message),boost::asio::transfer_all(),ignored_error);}}Finally,handleanyexceptions.

最后,

处理异常。

全部源码:

主函数

intmain(){try{Weneedtocreateaserverobjecttoacceptincomingclientconnections.Theboost::asio::io_serviceobjectprovidesI/Oservices,suchassockets,thattheserverobjectwilluse.

我们需要创建一个服务器对象,用来接受客户端的连接。boost::asio::io_service对象提供了像sockets这样的I/O服务,这些服务都是服务器对象将要使用的。

运行boost::asio::io_service对象,它将执行你想要的异步操作。

classtcp_server{public:TheconstructorinitialisesanacceptortolistenonTCPport13.

构造函数初始化一个用于监听TCP端口13的接收器。

tcp_server(boost::asio::io_service&io_service):acceptor_(io_service,tcp::endpoint(tcp::v4(),13)){start_accept();}private:Thefunctionstart_accept()createsasocketandinitiatesanasynchronousacceptoperationtowaitforanewconnection.

函数start_accept()创建一个socket,同时启动一个异步接收操作去等待一个新的连接。

voidstart_accept(){tcp_connection::pointernew_connection=tcp_connection::create(acceptor_.io_service());acceptor_.async_accept(new_connection->socket(),boost::bind(&tcp_server::handle_accept,this,new_connection,boost::asio::placeholders::error));}Thefunctionhandle_accept()iscalledwhentheasynchronousacceptoperationinitiatedbystart_accept()finishes.Itservicestheclientrequest,andthencallsstart_accept()toinitiatethenextacceptoperation.

当start_accept()启动的异步接收操作完成后,handle_accept()函数将被调用。它响应客户端的请求,然后调用start_accept()函数去启动另一个接收操作。

Wewilluseshared_ptrandenable_shared_from_thisbecausewewanttokeepthetcp_connectionobjectaliveaslongasthereisanoperationthatreferstoit.

我们希望只要还有一个操作涉及tcp_connection对象,该对象就是有效的。因此我们使用shared_ptr和enable_shared_from_this。

classtcp_connection:publicboost::enable_shared_from_this{public:typedefboost::shared_ptrpointer;staticpointercreate(boost::asio::io_service&io_service){returnpointer(newtcp_connection(io_service));}tcp::socket&socket(){returnsocket_;}Inthefunctionstart(),wecallboost::asio::async_write()toservethedatatotheclient.Notethatweareusingboost::asio::async_write(),ratherthanboost::asio::ip::tcp::socket::async_write_some(),toensurethattheentireblockofdataissent.

在start()函数中,我们调用boost::asio::async_write()为客户端处理数据。注意:为了确保数据被整块发送,我们使用的是boost::asio::async_write(),而不是boost::asio::ip::tcp::socket::async_write_some()。

voidstart(){Thedatatobesentisstoredintheclassmembermessage_asweneedtokeepthedatavaliduntiltheasynchronousoperationiscomplete.

要发送的数据保存在类成员变量message_中,在异步操作完成前我们需要保证数据的有效性。

Wheninitiatingtheasynchronousoperation,andifusingboost::bind(),youmustspecifyonlytheargumentsthatmatchthehandler'sparameterlist.Inthisprogram,bothoftheargumentplaceholders(boost::asio::placeholders::errorandboost::asio::placeholders::bytes_transferred)couldpotentiallyhavebeenremoved,sincetheyarenotbeingusedinhandle_write().

当启动一个异步操作时,如果使用boost::bind(),你只需要指定一个符合句柄参数列表签名的参数。在本例中,任何一个参数占位符(boost::asio::placeholders::error和boost::asio::placeholders::bytes_transferred)皆可被隐式地移除,因为操作write()并没有使用它们。

boost::asio::async_write(socket_,boost::asio::buffer(message_),boost::bind(&tcp_connection::handle_write,shared_from_this(),boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));Anyfurtheractionsforthisclientconnectionarenowtheresponsibilityofhandle_write().

任何对客户端连接的下一步操作都由handle_write()函数负责处理。

Youmayhavenoticedthattheerror,andbytes_transferredparametersarenotusedinthebodyofthehandle_write()function.Ifparametersarenotneeded,itispossibletoremovethemfromthefunctionsothatitlookslike:

你可能已经注意到了:error和bytes_transferred参数并没有在handle_write()函数体内被应用。因此,如果参数并不是必须的,我们可以移除它们,如下所示:

voidhandle_write(){}Theboost::asio::async_write()callusedtoinitiatethecallcanthenbechangedtojust:

用来发起呼叫的boost::asio::async_write()函数通常可以被改写成下面这样:

THE END
1.双色球方案一等奖 ●●● ● 浮动/5,000,000魔币 选6+1中6+1 二等奖 ●●● 浮动/500,000魔币 选6+1中6+0 三等奖 ●●● ● 3000魔币 选6+1中5+1 四等奖 ●●● 200魔币 选6+1中5+0或中4+1 ●●● ● 五等奖 ●●● 10魔币 选6+1中4+0或中3+1 ●●● ● 六等奖 ●● ● 5魔币 选https://6.17500.cn/?lottery=bet&h=2&lotteryId=ssq&schemeId=9195049
2.首页彩票新闻中心介绍电脑福彩刮刮乐福彩游戏政策法规福彩公益双色球游戏的乐趣和魅力 今天 让我们一起了解 双色球游戏的更多小乐趣 【双色球复式投注指南】 复式投注 是指所选号码个数超过单式投注的号码个数, 所选号码可组合为每一种单式投注方式的多注彩票的投注。 那么,双色球游戏的复式投注有几种?怎么玩? http://www.gdfc.org.cn/datas/content/content_271292.html
3.C++猜数字代码continue;//重新返回到玩家猜数 } if(num<t_an){//如果玩家猜小了 cout<<"猜小了"<<endl;//告诉玩家这个数猜小了 continue;//重新返回到玩家猜数 } if(num==t_an){//如果玩家猜对了 cout<<"猜对了"<<endl;//告诉玩家猜对了 break;//游戏结束 https://blog.csdn.net/scarch2983/article/details/144092692
4.c++课程设计彩票游戏(19页)c++课程设计--彩票游戏.pdf 19页VIP内容提供方:xieliandimei 大小:525 KB 字数:约1.25万字 发布时间:2020-06-13发布于江西 浏览人气:60 下载次数:仅上传者可见 收藏次数:0 需要金币:*** 金币 (10金币=人民币1元)c++课程设计--彩票游戏.pdf 关闭预览 想预览更多内容,点击免费在线预览全文 免费https://max.book118.com/html/2020/0609/5112103000002303.shtm
5.福彩C++代码课程资源福彩C++代码 课程资源 - C\/C++Ag**ni 上传7KB 文件格式 txt 有关于C++课程设计当中的,有关于福彩的代码 点赞(0) 踩踩(0) 反馈 所需:1 积分 开源Java 扫雷游戏JMine 2024-11-16 15:20:16 积分:1 math-proofreading 2024-11-16 15:15:46 积分:1 Python数学建模算法与应用 2024-11-16 https://www.coder100.com/index/index/content/id/1835565
6.娱乐最新什么冰点下的幸福第6集正在播放c++1107影片介绍 94.76MB 53%好评70420人) 福利彩怎么购买影片介绍 66347727是广州什么区的电话影片介绍 刘伯温四肖八码凤凰网游戏股票影片介绍 详情 霍去病儿子影片介绍 47113牛魔王影片介绍 22.65MB 42%好评61110人) 乐发彩票手机购彩大厅在哪里影片介绍 河北唐县最新兑换码 国际导航系统有哪几种影片介http://www.tpisb.com/ungyyrp.shtml
7.入口?游戏点击蚁王第2集正在播放c+=c++,c+8,++c影片介绍 94.27MB 87%好评33159人) 亿博网络影片介绍 浙江排三走,图,列表影片介绍 网赌有没有办法不被抓影片介绍 21.95MB 45搏通福彩app下载最新版 cx16z3fg1 企业网站排行榜 发条娱乐是不是正规游戏 奇异果 下载 巴西甲级联赛2020 123696c.oom噢门开彩结果 pc免费单机http://www.kzqhu.com/nndpuyt.shtml
8.福彩双色球选号器源代码C++福彩游戏源代码 C++ 福彩游戏 源代码 设计的很科学 符合各个学校的考试要求 上传者:yogurt1231时间:2011-05-04 Python双色球系统源代码 双色球是中国福利彩票的一种玩法,是一种大众喜爱的彩票游戏。双色球游戏规则是从1至33共33个红色球中选择6个号码,从1至16共16个蓝色球中选择1个号码,组成一注彩票。每https://www.iteye.com/resource/jqtony-2638904
9.日前2022200期福彩3D试机号码福彩3D试机号查询08月25日,拜登退选支持哈里斯首日:民主党竞选节奏加快,筹款打破纪录,3d试机号近80期_3d最近80期试机号_福彩3d试机号近80期_3d|3d试机号|v3.0.8 lutu轻量版线路检测页的优点_澎湃新闻-The Paper-|的优点|八重神子触摸游戏2.0免费汉化版下载安装-八重神子触摸游戏|八重神子触摸游戏。 http://www.och.cn/oppo/soft/20240825/50994865.shtml
10.C++进阶:STL算法18排列组合算法3. 练习 0人点赞 C/C++开发课程 更多精彩内容,就在简书APP "小礼物走一走,来简书关注我" 赞赏支持还没有人赞赏,支持一下 jdzhangxin尝试尝试再尝试 总资产9共写了19.9W字获得410个赞共325个粉丝 关注https://www.jianshu.com/p/b51daa6dbd1b
11.创建Unity的Googlesignin插件是为了在Unity游戏中实现使用Google账号进行登录和授权的功能。该插件可以通过Google Sign-In API来实现。 Google Sign-In是一种基于OAuth 2.0协议的身份验https://cloud.tencent.com/developer/information/%E5%88%9B%E5%BB%BAUnity%E7%9A%84Google%20sign%20in%E6%8F%92%E4%BB%B6
12.最新官方网站登录入口伟德亚洲娱乐城总部,亚娱体育官方网站下载app,可以赢钱的游戏软件,捕新2国际娱乐城,开元在线游戏飞星体育网,到哪里可以找到信誉最好的娱乐城?,乐动体育登录,捕名流娱乐城 ,创高体育ag亚游体育手机app官网注册,u球app官方版下载,凤凰备用网站址,捕明博体育登录,澳门博彩旅游业 时时彩能赚钱吗,竞彩推荐APP排行榜,福彩 https://6.00000666.com/shows/1598957.html