boost asio 网络编程,boost asio socket

  boost asio 网络编程,boost asio socket

  boost:asio:ip:tcp实现网络通信的小例子(转载)-fengyc-博客园

  boost:asio:ip:tcp实现网络通信的一个小例子(转载)贴于2012-03-21 14:15 fengyc阅读(1289)评论(0)编辑收藏

  原地址:http://www.cppblog.com/janvy/archive/2010/03/24/110478.html

  服务器端:

  助推。Asio是一个跨平台的网络和底层IO C编程库,它使用现代C技术来实现统一的异步调用模型。

  头文件

  #包含boost/asio.hpp命名空间

  使用命名空间boost:asio;ASIO图书馆可以使用TCP、UDP、ICMP和串行端口发送/接收数据。这里首先介绍TCP协议的读写操作。

  对于读写方法,ASIO支持同步和异步方法,其中第一种是同步方法。请介绍一下下面的同步方法:

  大家好!我是同步的!

  我的主要特点就是坚持!所有操作都要完成或者出错才会返回,而我的坚持却叫堵,真的很郁闷~ ~(场下嘘声)。其实这样也是有好处的,比如逻辑清晰,编程容易。

  在服务器端,我会做一个socket给acceptor对象,让它等待客户端连接,然后通过这个socket和客户端通信。所有的交流都是以阻塞的方式进行的,只有读完或写完才会返回。

  对于客户端来说也是如此。这时候,我会拿插座连接服务器。当然,我会在连接或出错后返回。最后,我会用阻塞的方式与服务器通信。

  有人认为同步模式不如异步模式高效,但这其实是一种片面的理解。在单线程的情况下,这可能是正确的。我不能用耗时的网络操作去做其他事情,这不是一个好的统筹方法。但是,这个问题可以通过多线程来避免。比如在服务器端,其中一个线程负责等待客户端的连接,连接进来后将套接字交给另一个线程与客户端进行通信,这样在与一个客户端通信的同时可以接受其他客户端的连接,完全解放了主线程。

  我的介绍到这里了,谢谢!

  好了,感谢同步模式的自我介绍,现在放出同步模式的演示代码(起立鼓掌!):

  server # includeiostrem # include boot/asio . hppusingnamespace boost:asio;Int (int argc,char * argv[]){//所有asio类都需要io_service对象io _ serviceiosevIP:TCP:acceptoracceptor(iosev,ip:tcp:endpoint(ip:tcp:v4(),1000));for(;){//socket对象IP:TCP:socket socket(iosev);//等待客户端连接到acceptor . accept(socket);//显示连接的客户端STD:cout socket . remote _ endpoint()。address()STD:endl;//向客户端发送helloworld!boost:system:error _ codeec;socket . write _ some(buffer( hello world!),EC);//如果有错误,打印错误信息If(EC){ STD:cout boost:system:system _ error(EC)。what()STD:endl;打破;}//与当前客户交互完成后,继续循环等待下一个客户连接} return0} client # includeiostrem # include boost/asio . hppusingnamespace boost:asio;Int (int argc,char * argv[]){//所有asio类都需要io_service对象io _ serviceiosev//socket对象IP:TCP:socket socket(iosev);//连接端点,这里使用本地连接。可以修改IP地址来测试远程连接IP: TCP:端点EP(IP:address _ v4:from _ string( 127 . 0 . 0 . 1 ),1000);//连接服务器boost:system:error _ codeec;socket.connect(ep,EC);//如果有错误,打印错误信息If(EC){ STD:cout boost:system:system _ error(EC)。what()STD:endl;return-1;}//接收数据charbuf[100];size _ tlen=socket . read _ some(buffer(buf),EC);std:cout.write(buf,len);return0}从演示代码中可以知道

  音频流输入输出接口的三氯苯酚协议通过boost:asio:ip名空间下的传输控制协议类进行通信100 .互联网协议(Internet Protocol)地址(地址,地址_v4,地址_v6),端口号和协议版本组成一个端点(tcp:端点).用于在服务器端生成tcp:接受者对象,并在指定端口上等待连接;或者在客户端连接到指定地址的服务器上1000插座。是服务器与客户端通信的桥梁,连接成功后所有的读写都是通过窝对象实现的,当窝析构后,连接自动断开106 .音频流输入输出接口读写所用的缓冲区用缓冲器函数生成,这个函数生成的是一个音频流输入输出接口内部使用的缓冲区类,它能把数组、指针(同时指定大小)、std:vector、std:string、boost:数组包装成缓冲区类106 .音频流输入输出接口中的函数、类方法都接受一个升压:系统:错误代码类型的数据,用于提供出错码。它可以转换成弯曲件测试是否出错,并通过升压:系统:系统_错误类获得详细的出错信息。另外,也可以不向音频流输入输出接口的函数或方法提供boost:系统:错误代码这时如果出错的话就会直接抛出异常,异常类型就是升压:系统:系统错误(它是从标准:运行时错误继承的)。另一个例子::::::::我稍稍整理了下,就是加了点注释,很基本的东西,大家可以参考窝的几个流程,我上面也有提示的,希望对大家有所帮助。最后,如果大家有什么好的方法希望能让我也分享下,谢谢!

  #包含boost/asio.hpp

  #包含升压/绑定. hpp

  #包含boost/shared_ptr.hpp

  #包含boost/enable _ shared _ from _ thisHPP

  #包括输入输出流

  使用boost:asio:IP:TCP;

  #definemax_len 1024

  classclientSession

  :public boost:enable _ shared _ from _ this客户端会话

  {

  公共:

  客户端会话(boost:asio:io _ service io服务)

  :m_socket(ioservice)

  {

  memset(data_, ,sizeof(data _));

  }

  ~clientSession()

  {}

  tcp:套接字套接字()

  {

  returnm _ socket

  }

  voidstart()

  {

  boost:asio:异步写入(m_socket,

  boost:asio:buffer(链接成功!),

  boost:bind(客户端会话:handle _ write,shared_from_this(),

  boost:asio:占位符:错误));

  /*异步读取跟客户端一样,还是不能进入句柄_读取函数,如果你能找到问题所在,请告诉我,谢谢*///- 已经解决,boost:asio:async_read(.)读取的字节长度不能大于数据流的长度,否则就会进入

  //ioservice.run()线程等待,阅读后面的就不执行了。

  //boost:asio:async _ read(m _ socket,boost:asio:buffer(data_,max_len),

  //boost:bind(客户端会话:handle _ read,shared_from_this(),

  //boost:asio:placeholders:error));

  //max_len可以换成较小的数字,就会发现异步_读取_一些可以连续接收未收完的数据

  m _ socket。async _ read _ some(boost:asio:buffer(data _,max_len),

  boost:bind(客户端会话:handle _ read,shared_from_this(),

  boost:asio:占位符:错误));

  }

  私人:

  void handle _ write(const boost:system:error _ code错误)

  {

  如果(错误)

  {

  m _ socket。close();

  }

  }

  void handle _ read(const boost:system:error _ code error)

  {

  如果(!错误)

  {

  STD:cout data _ STD:endl;

  //boost:asio:async _ read(m _ socket,boost:asio:buffer(data_,max_len),

  //boost:bind(客户端会话:handle _ read,shared_from_this(),

  //boost:asio:placeholders:error));

  m _ socket。async _ read _ some(boost:asio:buffer(data _,max_len),

  boost:bind(客户端会话:handle _ read,shared_from_this(),

  boost:asio:占位符:错误));

  }

  其他

  {

  m _ socket。close();

  }

  }

  私人:

  TCP:socket TM _ socket;

  chardata _[max _ len];

  };

  classserverApp

  {

  typedefboost:shared _ ptr客户端会话session _ ptr

  公共:

  服务器应用(boost:asio:io _ service io服务,tcp:endpoint端点)

  :m_ioservice(ioservice),

  acceptor_(ioservice,端点)

  {

  session _ ptr new _ session(新客户端会话(io服务));

  接受者_。异步接受(新会话套接字(),

  boost:bind(服务器app:handle _ accept,this,boost:asio:占位符:错误,

  new _ session);

  }

  ~serverApp()

  {

  }

  私人:

  void handle _ accept(const boost:system:error _ code error,session_ptr session)

  {

  如果(!错误)

  {

  获得一个新客户!STD:endl;

  //实现对每个客户端的数据处理

  会话开始();

  //在这就应该看出为什么要封会议类了吧,每一个会议就是一个客户端

  session _ ptr new _ session(新客户端会话(m _ io服务));

  接受者_。异步接受(新会话套接字(),

  boost:bind(服务器app:handle _ accept,this,boost:asio:占位符:错误,

  new _ session);

  }

  }

  私人:

  boost:asio:io _ service m _ io服务;

  TCP:acceptor acceptor _;

  };

  intmain(intargc,char*argv[])

  {

  boost:asio:io _ service myIoService;

  短端口=8100/* argv[1]*/;

  //我们用的是inet4

  tcp:端点端点(tcp:v4(),端口);

  //终端(可以看作sockaddr_in)完成后,就要接受了

  serverApp sa(myIoService,endPoint);

  //数据收发逻辑

  myio服务。run();

  返回0

  }

boost asio 网络编程,boost asio socket