找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4929|回复: 0

Boost Asio学习测试

[复制链接]
发表于 2011-12-4 09:57:18 | 显示全部楼层 |阅读模式
  1. 客户端:
  2. view plain
  3. #include <boost/asio.hpp>
  4. #include <boost/bind.hpp>
  5. #include <boost/shared_ptr.hpp>
  6. using boost::asio::ip::tcp;
  7. class client
  8. {
  9. public:
  10. client(boost::asio::io_service& io_service,tcp::endpoint& endpoint)
  11. : socket(io_service)//这里就把socket实例化了
  12. {
  13. //连接服务端 connect
  14. socket.async_connect(endpoint,
  15. boost::bind(&client::handle_connect,this,boost::asio::placeholders::error)
  16. );
  17. memset(getBuffer,‘\0′,1024);
  18. }
  19. ~client()
  20. {}
  21. private:
  22. void handle_connect(const boost::system::error_code& error)
  23. {
  24. if(!error)
  25. {
  26. //一连上,就向服务端发送信息
  27. boost::asio::async_write(socket,boost::asio::buffer(“hello,server!”),
  28. boost::bind(&client::handle_write,this,boost::asio::placeholders::error));
  29. /**读取服务端发下来的信息
  30. *这里很奇怪,用async_read根本就不能进入handle_read函数
  31. **/
  32. // --已经解决,boost::asio::async_read(...)读取的字节长度不能大于数据流的长度,否则就会进入
  33. // ioservice.run()线程等待,read后面的就不执行了。
  34. //boost::asio::async_read(socket,
  35. // boost::asio::buffer(getBuffer,1024),
  36. // boost::bind(&client::handle_read,this,boost::asio::placeholders::error)
  37. // );
  38. socket.async_read_some(boost::asio::buffer(getBuffer,1024),
  39. boost::bind(&client::handle_read,this,boost::asio::placeholders::error)
  40. );
  41. }
  42. else
  43. {
  44. socket.close();
  45. }
  46. }
  47. void handle_read(const boost::system::error_code& error)
  48. {
  49. if(!error)
  50. {
  51. std::cout << getBuffer << std::endl;
  52. //boost::asio::async_read(socket,
  53. // boost::asio::buffer(getBuffer,1024),
  54. // boost::bind(&client::handle_read,this,boost::asio::placeholders::error)
  55. // );
  56. //这样就可以实现循环读取了,相当于while(1)
  57. //当然,到了这里,做过网络的朋友就应该相当熟悉了,一些逻辑就可以自行扩展了
  58. //想做聊天室的朋友可以用多线程来实现
  59. socket.async_read_some(
  60. boost::asio::buffer(getBuffer,1024),
  61. boost::bind(&client::handle_read,this,boost::asio::placeholders::error)
  62. );
  63. }
  64. else
  65. {
  66. socket.close();
  67. }
  68. }
  69. void handle_write(const boost::system::error_code& error)
  70. {
  71. }
  72. private:
  73. tcp::socket socket;
  74. char getBuffer[1024];
  75. };
  76. int main(int argc,char* argv[])
  77. {
  78. //if(argc != 3)
  79. //{
  80. // std::cerr << “Usage: chat_client <host> <port>\n”;
  81. // return 1;
  82. //}
  83. //我觉IO_SERVICE是一个基本性的接口,基本上通常用到的类实例都需要通过它来构造
  84. //功能我们可以看似socket
  85. boost::asio::io_service io_service;
  86. //这个终端就是服务器
  87. //它的定义就可以看作时sockaddr_in,我们用它来定义IP和PORT
  88. tcp::endpoint endpoint(boost::asio::ip::address_v4::from_string("192.168.1.119"/*argv[1]*/),8100/*argv[2]*/);
  89. //既然socket和sockaddr_in已经定义好了,那么,就可以CONNECT了
  90. //之所以为了要把连接和数据处理封成一个类,就是为了方便管理数据,这点在服务端就会有明显的感觉了
  91. boost::shared_ptr<client> client_ptr(new client(io_service,endpoint));
  92. //执行收发数据的函数
  93. io_service.run();
  94. return 0;
  95. }
  96. 服务器代码:
  97. view plain
  98. Servier.cpp
  99. #include <boost/asio.hpp>
  100. #include <boost/bind.hpp>
  101. #include <boost/shared_ptr.hpp>
  102. #include <boost/enable_shared_from_this.hpp>
  103. #include <iostream>
  104. using boost::asio::ip::tcp;
  105. #define max_len 1024
  106. class clientSession
  107. :public boost::enable_shared_from_this<clientSession>
  108. {
  109. public:
  110. clientSession(boost::asio::io_service& ioservice)
  111. :m_socket(ioservice)
  112. {
  113. memset(data_,‘\0′,sizeof(data_));
  114. }
  115. ~clientSession()
  116. {}
  117. tcp::socket& socket()
  118. {
  119. return m_socket;
  120. }
  121. void start()
  122. {
  123. boost::asio::async_write(m_socket,
  124. boost::asio::buffer(“link successed!”),
  125. boost::bind(&clientSession::handle_write,shared_from_this(),
  126. boost::asio::placeholders::error));
  127. /*async_read跟客户端一样,还是不能进入handle_read函数,如果你能找到问题所在,请告诉我,谢谢*/
  128. // --已经解决,boost::asio::async_read(...)读取的字节长度不能大于数据流的长度,否则就会进入
  129. // ioservice.run()线程等待,read后面的就不执行了。
  130. //boost::asio::async_read(m_socket,boost::asio::buffer(data_,max_len),
  131. // boost::bind(&clientSession::handle_read,shared_from_this(),
  132. // boost::asio::placeholders::error));
  133. //max_len可以换成较小的数字,就会发现async_read_some可以连续接收未收完的数据
  134. m_socket.async_read_some(boost::asio::buffer(data_,max_len),
  135. boost::bind(&clientSession::handle_read,shared_from_this(),
  136. boost::asio::placeholders::error));
  137. }
  138. private:
  139. void handle_write(const boost::system::error_code& error)
  140. {
  141. if(error)
  142. {
  143. m_socket.close();
  144. }
  145. }
  146. void handle_read(const boost::system::error_code& error)
  147. {
  148. if(!error)
  149. {
  150. std::cout << data_ << std::endl;
  151. //boost::asio::async_read(m_socket,boost::asio::buffer(data_,max_len),
  152. // boost::bind(&clientSession::handle_read,shared_from_this(),
  153. // boost::asio::placeholders::error));
  154. m_socket.async_read_some(boost::asio::buffer(data_,max_len),
  155. boost::bind(&clientSession::handle_read,shared_from_this(),
  156. boost::asio::placeholders::error));
  157. }
  158. else
  159. {
  160. m_socket.close();
  161. }
  162. }
  163. private:
  164. tcp::socket m_socket;
  165. char data_[max_len];
  166. };
  167. class serverApp
  168. {
  169. typedef boost::shared_ptr<clientSession> session_ptr;
  170. public:
  171. serverApp(boost::asio::io_service& ioservice,tcp::endpoint& endpoint)
  172. :m_ioservice(ioservice),
  173. acceptor_(ioservice,endpoint)
  174. {
  175. session_ptr new_session(new clientSession(ioservice));
  176. acceptor_.async_accept(new_session->socket(),
  177. boost::bind(&serverApp::handle_accept,this,boost::asio::placeholders::error,
  178. new_session));
  179. }
  180. ~serverApp()
  181. {
  182. }
  183. private:
  184. void handle_accept(const boost::system::error_code& error,session_ptr& session)
  185. {
  186. if(!error)
  187. {
  188. std::cout << “get a new client!” << std::endl;
  189. //实现对每个客户端的数据处理
  190. session->start();
  191. //在这就应该看出为什么要封session类了吧,每一个session就是一个客户端
  192. session_ptr new_session(new clientSession(m_ioservice));
  193. acceptor_.async_accept(new_session->socket(),
  194. boost::bind(&serverApp::handle_accept,this,boost::asio::placeholders::error,
  195. new_session));
  196. }
  197. }
  198. private:
  199. boost::asio::io_service& m_ioservice;
  200. tcp::acceptor acceptor_;
  201. };
  202. int main(int argc , char* argv[])
  203. {
  204. boost::asio::io_service myIoService;
  205. short port = 8100/*argv[1]*/;
  206. //我们用的是inet4
  207. tcp::endpoint endPoint(tcp::v4(),port);
  208. //终端(可以看作sockaddr_in)完成后,就要accept了
  209. serverApp sa(myIoService,endPoint);
  210. //数据收发逻辑
  211. myIoService.run();
  212. return 0;
  213. }
复制代码
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-5 06:45 , Processed in 0.016725 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表