boost::asio Programming - Synchronous TCP
boost.asio library is a cross-platform network and underlying IO C++ programming library. It uses modern C++ techniques to implement a unified asynchronous calling model.
boost.asio library supports TCP, UDP, and ICMP communication protocols.
The following introduces the synchronous TCP mode:
Hello everyone! I am in sync mode!
My main characteristic is persistence! All operations must be completed or make an error before returning. However, my persistence is called blocking by everyone, which is really depressing~~ (The audience booed), in fact, this is
There are also benefits, such as clear logic and easier programming.
On the server side, I will make a socket and give it to the acceptor object, and let it wait for the client to connect. After connecting, I will communicate with the client through this socket.
All communications are performed in a blocking manner and will not return until reading or writing is completed.
The same goes for the client. At this time, I will use the socket to connect to the server. Of course, I will only return when the connection is connected or an error occurs. In the end, I will communicate with the server in a blocking manner.
Some people think that the synchronous method is not as efficient as the asynchronous method. In fact, this is a one-sided understanding. This may be true in a single-threaded case, where I can't use the time spent on network operations to do anything else
Emotion is not a good coordination method. However, this problem can be avoided through multi-threading. For example, on the server side, one of the threads is responsible for waiting for the client to connect, and after the connection comes in, the socket is handed over to another thread.
Communicate with the client, so that while communicating with one client, you can also accept connections from other clients, and the main thread is completely freed.
That’s my introduction, thank you everyone!
Synchronization mode sample code:
Server side
// BoostTcpServer.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "boost/asio.hpp" #include "boost/thread.hpp" using namespace std; using namespace boost::asio; #ifdef _MSC_VER #define _WIN32_WINNT 0X0501 //避免VC下编译警告 #endif #define PORT 1000 #define IPV6 //#define IPV4 int _tmain(int argc, _TCHAR* argv[]) { // 所有asio类都需要io_service对象 io_service iosev; //创建用于接收客户端连接的acceptor对象 #ifdef IPV4 ip::tcp::acceptor acceptor(iosev,ip::tcp::endpoint(ip::tcp::v4(), PORT)); #endif #ifdef IPV6 ip::tcp::acceptor acceptor(iosev,ip::tcp::endpoint(ip::tcp::v6(), PORT)); #endif while (true) { // socket对象 ip::tcp::socket socket(iosev); // 等待直到客户端连接进来 acceptor.accept(socket); // 显示连接进来的客户端 std::cout <<"remote ip:"<<socket.remote_endpoint().address()<<endl; std::cout <<"remote port:"<<socket.remote_endpoint().port() << std::endl; char buf[2048]; boost::system::error_code ec; while(1) { socket.read_some(buffer(buf),ec); if (ec) { std::cout <<boost::system::system_error(ec).what() << std::endl; break ; } std::cout<<"recv msg:"<<buf<<endl; if(strcmp(buf,"bye")==0)//收到结束消息结束客户端连接 { break; } socket.write_some(buffer("I heared you!\n"),ec); if (ec) { std::cout <<boost::system::system_error(ec).what() << std::endl; break ; } } socket.close(); // 与当前客户交互完成后循环继续等待下一客户连接 } return 0; }
Client side
// BoostTcpClient.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "boost/asio.hpp" using namespace boost::asio; #ifdef _MSC_VER #define _WIN32_WINNT 0X0501 //避免VC下编译警告 #endif #define PORT 1000 #define IPV6 //#define IPV4 int _tmain(int argc, _TCHAR* argv[]) { // 所有asio类都需要io_service对象 io_service iosev; // socket对象 ip::tcp::socket socket(iosev); // 连接端点,这里使用了本机连接,可以修改IP地址测试远程连接 #ifdef IPV4 ip::address_v4 address=ip::address_v4::from_string("127.0.0.1"); #endif #ifdef IPV6 //"0:0:0:0:0:0:0:1"为IPV6的本机回环地址,类似于"127.0.0.1" ip::address_v6 address=ip::address_v6::from_string("0:0:0:0:0:0:0:1"); #endif ip::tcp::endpoint ep(address, PORT); // 连接服务器 boost::system::error_code ec; socket.connect(ep,ec); // 如果出错,打印出错信息 if (ec) { std::cout << boost::system::system_error(ec).what() << std::endl; return -1; } //循环发送和接收数据 for(int i=0;i<5;++i) { //发送数据 socket.write_some(buffer("hello"), ec); // 接收数据 char buf[100]; size_t len=socket.read_some(buffer(buf), ec); std::cout.write(buf, len); Sleep(500); } //发送与服务端约定好的结束语,由服务端断链 socket.write_some(buffer("bye"), ec); getchar(); return 0; }
The code is compatible with both IPV4 and IPV6 IP protocols. Use macro definition to choose which IP protocol to use. Of course, the client The protocol with the server must be consistent for normal communication.
Thanks for reading, I hope it can help everyone. For more related articles, please pay attention to the PHP Chinese website (www.php.cn)!