boost::asio-Programmierung – Synchrones TCP
boost.asio-Bibliothek ist ein plattformübergreifendes Netzwerk und eine zugrunde liegende IO-C++-Programmierbibliothek. Sie verwendet moderne C++-Techniken, um ein einheitliches asynchrones Aufrufmodell zu implementieren.
Die boost.asio-Bibliothek unterstützt die Kommunikationsprotokolle TCP, UDP und ICMP.
Im Folgenden wird der synchrone TCP-Modus vorgestellt:
Hallo zusammen! Ich bin im Synchronisierungsmodus!
Mein Hauptmerkmal ist Beharrlichkeit! Alle Vorgänge müssen abgeschlossen sein oder einen Fehler machen, bevor sie zurückkehren. Meine Beharrlichkeit wird jedoch von allen als Blockieren bezeichnet, was in der Tat wirklich deprimierend ist
Es gibt auch Vorteile wie eine klare Logik und eine einfachere Programmierung.
Auf der Serverseite erstelle ich einen Socket, übergebe ihn an das Akzeptorobjekt und lasse es warten, bis der Client eine Verbindung herstellt. Nach der Verbindung kommuniziere ich mit dem Client über diesen Socket.
Die gesamte Kommunikation erfolgt blockierend und erfolgt erst nach Abschluss des Lese- oder Schreibvorgangs.
Dasselbe gilt für den Client. Zu diesem Zeitpunkt werde ich den Socket verwenden, um eine Verbindung zum Server herzustellen. Natürlich werde ich nur zurückkehren, wenn die Verbindung hergestellt ist oder ein Fehler auftritt Am Ende kommuniziere ich blockierend mit dem Server.
Einige Leute denken, dass die synchrone Methode nicht so effizient ist wie die asynchrone Methode. Tatsächlich ist dies ein einseitiges Verständnis. Dies kann in einem Single-Thread-Fall zutreffen, in dem ich die für Netzwerkoperationen aufgewendete Zeit nicht für andere Zwecke nutzen kann
Emotionen sind keine gute Koordinationsmethode. Dieses Problem kann jedoch durch Multithreading vermieden werden. Auf der Serverseite ist beispielsweise einer der Threads dafür verantwortlich, auf die Verbindung des Clients zu warten, und nachdem die Verbindung hergestellt wurde, wird der Socket an einen anderen Thread übergeben.
Kommunizieren Sie mit dem Client, sodass Sie bei der Kommunikation mit einem Client auch Verbindungen von anderen Clients akzeptieren können und der Hauptthread vollständig freigegeben wird.
Das ist meine Einführung, vielen Dank an alle!
Beispielcode für den Synchronisierungsmodus:
Serverseite
// 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; }
Clientseite
// 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; }
Der Code ist mit zwei IP-Protokollen kompatibel, IPV4 und IPV6. Verwenden Sie Makrodefinitionen, um auszuwählen, welches IP-Protokoll verwendet werden soll. Natürlich müssen die Protokolle des Clients und des Servers für die normale Kommunikation konsistent sein.
Vielen Dank fürs Lesen, ich hoffe, es kann allen helfen. Weitere verwandte Artikel finden Sie auf der chinesischen PHP-Website (www.php.cn)!