博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
boost库在工作(29)网络客户端之四
阅读量:4162 次
发布时间:2019-05-26

本文共 2748 字,大约阅读时间需要 9 分钟。

当客户端连接到服务器之后,想要做什么事情呢?其实就跟一个人去看医生一样,先去挂一个号,然后再根据排队的号去看医生,然后再根据医生的处方进行治疗。因此,在客户端和服务器设计上,一般有一条重要的原则,就是作为客户端要主动发起数据给服务器,让服务器知道客户端是来做什么事情的。比如同一个服务器的端口上,可以提供很多种客户端连接,像HTTP这样的服务器,也就面临着很多不同浏览器连接上来,而服务器要区分不同的浏览器来做不同的事情,那么就需要知道浏览器来做什么事情的,因而浏览器连接成功之后,首先发送数据给服务器,说明协议的版本,浏览器的名称,能接收什么样的数据等内容。这样服务器,就会根据客户端的情况进行区分,放到不同的任务处理队列里,这样服务器兼容处理不同版本协议的客户端情况,实现向下兼容所有以前的版本,达到平滑向前升级的功能。在网络里按服务器与客户端设计时,服务器往往设计上考虑是升级时间比较长,而客户端是随时可以更换或者升级的。这样就导致服务器要兼容不同的版本,以便适应不同的用户需求。比如目前移动系统更新很快,在移动系统开发的APP往往是不同的OS版本,做出来的功能也有区别,但是用户会分布在不同OS的版本上,导致客户端也有新旧之分了,在android版本1.6是1.0版本的客户端,而在android版本2.0是2.0版本的客户端,在android版本4.2是3.0版本的客户端。在这种情况之下,为了不同版本的用户,还继续使用提供的服务,那么就得在服务器端使用不同兼容策略,才可以维护新旧客户的满意度,才可以让旧的客户继续成为你的客户,因为丢失一个旧客户,要花三倍成本去开发一个新客户。在软件设计上与硬件设计上最大的不同,是在于软件设计上需要兼容旧版本,需要维护和升级,可能这就是软件上不能出现硬件上IC产业的原因。下面来看看发送数据的例子,代码如下:
// boost_022.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#include
#include
#include
bool SendRecvData(boost::asio::ip::tcp::socket& socket); //测试网络服务查询,连接。void Test(void){//定认一个查询端点对象。boost::asio::ip::tcp::resolver::query query("www.boost.org", "http");std::cout <<"host_name: " << query.host_name() << "service_name:" << query.service_name() << std::endl; //定义IO服务对象。boost::asio::io_service ioService; //定义解释对象。boost::asio::ip::tcp::resolver resolver(ioService);//进行域名或者服务解释,以便生成SOCKET内部使用的数据格式。boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);boost::asio::ip::tcp::resolver::iterator itEnd;if (iterator == itEnd){ return;} //解释成功之后, 显示解释后的IP地址和端口。boost::asio::ip::tcp::endpoint endpoint = iterator->endpoint();std:: cout << "host_ip:" << endpoint.address() << " port: " <
<< std::endl; //尝试连接服务器。boost::asio::ip::tcp::socket socket(ioService);boost::system::error_code errorCode = boost::asio::error::host_not_found; socket.close();socket.connect(*iterator,errorCode); //创建一个SOCKET同步连接,即阻塞式。if (errorCode){ //连接出错。 return;} std::cout << "ConnectSuccess" <
>strhttpVersion;unsigned int iStatusCode;responsePacket >>iStatusCode; std::string strStatusMessage; std::getline(responsePacket,strStatusMessage); //输出解释出来的数据。std::cout << "response:" << strhttpVersion << " " << iStatusCode <<" " << strStatusMessage<< std::endl; //return true;} int _tmain(int argc, _TCHAR* argv[]){Test(); system("pause"); return 0;}

在这个例子里,使用一个boost::asio::streambuf对象来构造发送数据包,然后通过boost::asio::write函数把数据通过网络SOCKET对象发送出去,最后为了接收服务器回应的数据,构造boost::asio::streambuf对象来保存数据,通过boost::asio::read_until函数来等服务器到来,直到条件结束。收到数据之后,就可以通过std::istream对象来解释回应的数据,然后把相应的数据输出到控制端窗口。

虽然这个例子短小,但还是把接收和发送的代码分成一个函数SendRecvData,这样更加容易理解和维护。在软件开发里,每个函数不超过屏幕一屏,就是最理想的函数,否则维护成本增加很多,每当开发人员查看代码,再滚屏时,思想就给滚掉了。并且这样可以把BUG减少到最低程度,大大地提高代码质量,提高软件开发效率。

转载地址:http://foixi.baihongyu.com/

你可能感兴趣的文章
让代码变得更优雅-Lombok
查看>>
解决Rhythmbox乱码
查看>>
豆瓣爱问共享资料插件发布啦
查看>>
Ubuntu10.10 CAJView安装 读取nh\kdh\caj文件 成功
查看>>
kermit的安装和配置
查看>>
vim 配置
查看>>
openocd zylin
查看>>
进程创建时文件系统处理
查看>>
进程创建时信号处理函数处理
查看>>
进程创建时信号处理
查看>>
进程创建时内存描述符处理
查看>>
进程创建时命名空间处理
查看>>
进程创建时IO处理
查看>>
进程创建时线程栈处理
查看>>
进程创建时pid分配
查看>>
进程创建时安全计算处理
查看>>
进程创建时cgroup处理
查看>>
idle进程创建
查看>>
内核线程创建
查看>>
linux elf tool readelf
查看>>