Boost.Asio C++ 網路程式設計之七:基於TCP的同步客戶端
在接下來的例子中:
1.客戶端使用一個使用者名稱(無密碼)登入到服務端
2.所有的連線由客戶端建立,當客戶端請求時服務端迴應
3.所有的請求和回覆都以換行符結尾(’\n’)
4.對於5秒鐘沒有ping操作的客戶端,服務端會自動斷開其連線
客戶端可以傳送如下請求:
1.獲得所有已連線客戶端的列表
2.客戶端可以ping,當它ping時,服務端返回ping ok或者pingclient_list_chaned
為了更有趣一點,我們增加了一些難度:
1.每個客戶端登入6個使用者連線,比如Johon,James,Lucy,Tracy,Frank和Abby
2.每個客戶端連線隨機地ping服務端(隨機7秒;這樣的話,服務端會時不時關閉一個連線)
基於TCP的同步客戶端
1.流程圖
2.實現
#ifdef WIN32 #define _WIN32_WINNT 0x0501 #include <stdio.h> #endif #include <boost/thread.hpp> #include <boost/bind.hpp> #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> using namespace boost::asio; io_service service; /** simple connection to server: - logs in just with username (no password) - all connections are initiated by the client: client asks, server answers - server disconnects any client that hasn't pinged for 5 seconds Possible requests: - gets a list of all connected clients - ping: the server answers either with "ping ok" or "ping client_list_changed" */ struct talk_to_svr { talk_to_svr(const std::string & username) : sock_(service), started_(true), username_(username) {} void connect(ip::tcp::endpoint ep) { sock_.connect(ep); } void loop() { // read answer to our login write("login " + username_ + "\n"); read_answer(); while (started_) { // 迴圈傳送ping請求 write_request(); read_answer(); int millis = rand() % 7000; std::cout << username_ << " postpone ping " << millis << " ms" << std::endl; boost::this_thread::sleep(boost::posix_time::millisec(millis)); } } std::string username() const { return username_; } private: void write_request() { write("ping\n"); } void read_answer() { already_read_ = 0; read(sock_, buffer(buff_), boost::bind(&talk_to_svr::read_complete, this, _1, _2)); process_msg(); } void process_msg() { std::string msg(buff_, already_read_); if (msg.find("login ") == 0) on_login(); else if (msg.find("ping") == 0) on_ping(msg); else if (msg.find("clients ") == 0) on_clients(msg); else std::cerr << "invalid msg " << msg << std::endl; } void on_login() { std::cout << username_ << " logged in" << std::endl; do_ask_clients(); } void on_ping(const std::string & msg) { std::istringstream in(msg); std::string answer; in >> answer >> answer; if (answer == "client_list_changed") do_ask_clients(); } void on_clients(const std::string & msg) { std::string clients = msg.substr(8); std::cout << username_ << ", new client list:" << clients; } // 獲得所有已連線客戶端的列表 void do_ask_clients() { write("ask_clients\n"); read_answer(); } void write(const std::string & msg) { sock_.write_some(buffer(msg)); } size_t read_complete(const boost::system::error_code & err, size_t bytes) { if (err) return 0; already_read_ = bytes; bool found = std::find(buff_, buff_ + bytes, '\n') < buff_ + bytes; return found ? 0 : 1; } private: ip::tcp::socket sock_; enum { max_msg = 1024 }; int already_read_; char buff_[max_msg]; bool started_; std::string username_; }; ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 8001); void run_client(const std::string & client_name) { talk_to_svr client(client_name); try { client.connect(ep); client.loop(); } catch (boost::system::system_error & err) { // 捕獲socket斷開原因 std::cout << "client terminated " << client.username() << "——" << err.what() << std::endl; } } int main(int argc, char* argv[]) { boost::thread_group threads; char* names[] = { "John", "James", "Lucy", "Tracy", "Frank", "Abby", 0 }; for (char ** name = names; *name; ++name) { threads.create_thread(boost::bind(run_client, *name)); boost::this_thread::sleep(boost::posix_time::millisec(100)); } threads.join_all(); system("pause"); }
相關推薦
Boost.Asio C++ 網路程式設計之七:基於TCP的同步客戶端
從本篇開始,我們會深入學習怎樣使用Boost.Asio建立更加複雜的客戶端和服務端應用。你可以執行並測試它們,而且在理解之後,你可以把它們做為框架來構造自己的應用。在接下來的例子中:1.客戶
Boost.Asio C++ 網路程式設計之十:基於TCP的非同步服務端
這個流程圖是相當複雜的:從Boost.Asio出來你可以看到4個箭頭指向on_accept,on_read,on_write和on_check_ping。這也就意味著你永遠不知道哪個非同步呼叫是下一個完成的呼叫,但是你可以確定的是它是這4個操作中的一個。基於TC
Boost.Asio C++ 網路程式設計之九:基於TCP的非同步客戶端
現在,是比較有趣(也比較難)的非同步實現! 當檢視流程圖時,你需要知道Boost.Asio代表由Boost.Asio執行的一個非同步呼叫。例如do_read(),Boost.Asio和on_read()代表了從do_read()到on_read()的邏輯流程,
Boost.Asio C++ 網路程式設計之二:同步和非同步
首先,非同步程式設計和同步程式設計是截然不同的。在同步程式設計中,所有的操作都是順序執行的,比如從socket中讀取(請求),然後寫入(迴應)到socket中。每一個操作都是阻塞的。因為操作是阻塞的,所以為了不影響主程式,當在socket上讀寫時,通常會建立一個
Boost.Asio C++ 網路程式設計之五:TCP回顯客戶端/服務端
回顯就是服務端將接收到的任何內容回發給客戶端顯示,然後關閉客戶端的連線。這個服務端可以處理任何數量的客戶端。每個客戶端連線之後傳送一個訊息,服務端接收到訊息後把它傳送回去。在那之後,服務端關閉連線。具體流程如下圖所示。 對於TCP而言,我們需要
Boost.Asio c++ 網路程式設計翻譯(30)[完結]
本地socket是一種只能被執行在主機上的應用訪問的socket。你可以使用本地socket來實現簡單的程序間通訊。你可以用客戶端或者服務端的方式來連線兩端。對於本地socket,端點時一個檔案,比如/tmp/whatever。很酷的一件事情是你可以給指定的檔案賦予許可權,從而禁止機器上指定的使用者在檔案上建
Boost.Asio c++ 網路程式設計翻譯(6)
io_service類 你應該已經發現大部分使用Boost.Asio編寫的程式碼都會使用幾個ios_service的例項。ios_service是這個庫裡面最重要的類;它負責和作業系統打交道,等待所有非同步操作的結束,然後為每一個非同步操作呼叫完成處理程式。 如果你選擇用同
linux網路程式設計之用多執行緒實現客戶端到服務端的通訊(基於udp)
1、開啟一個執行緒接受資料,主執行緒傳送資料的程式碼 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #includ
《TCP/IP網路程式設計》筆記5-基於TCP的伺服器端客戶端2
概述 上一節已經給出了服務端和客戶端的實現,為何還有這第二節? a. 上一節中的回聲客戶端是有問題的 問題的來源是tcp的傳輸特性:TCP傳輸的無邊界性。這樣造成了兩個後果,第一. client端呼叫write後並無法保證資料立即傳遞,可能發生
Python3 與 C# 網路程式設計之~ 網路基礎篇
最新版本檢視:https://www.cnblogs.com/dotnetcrazy/p/9919202.html 入門篇 官方文件:https://docs.python.org/3/library/ipc.html(程序間通訊和網路) 例項程式碼:https://github.com/lotapp/
網路程式設計之——七層模型與TCP三段握手與四次斷開
轉載請註明出處:https://blog.csdn.net/l1028386804/article/details/83046311 一、C/S架構 客戶端/服務端架構 二、OSI七層架構 七層模型,亦稱OSI(Open System Interconnection)參考模型,是
洞悉C++網路程式設計之tcp/ip和socket api
原文地址:https://blog.csdn.net/libaineu2004/article/details/79020403 TCP(Transmission Control Protocol) 傳輸控制協議 三次握手 TCP是主機對主機層的傳輸控制協議,提供可靠的連線服務,採用三次
c++ 網路程式設計之socket
windows 10 structures sockaddr, sockaddr_in sockaddr 和 sockaddr_in 同樣都是為了處理網路通訊的地址,包含了地址類別(familty),地址(ip),埠資訊。 sockaddr是給機器用的,
Linux-C網路程式設計之epoll函式
上文中說到如果從100的不同的地方取外賣,那麼epoll相當於一部手機,當外賣到達後,送貨員可以通知你,從而達到每去必得,少走很多路。 它是如何實現這些作用的呢? epoll的功能 epoll是select/poll的強化版,同是多路複用的函式,epoll
C++網路程式設計之select
select函式決定一個或者多個套接字(socket)的狀態,如果需要的話,等待執行非同步I/O。 int select( __in int nfds, __inout fd_set *readfds,
C# 網路程式設計之基於SMTP傳送電子郵件
本文主要講述基於C#網路程式設計的傳送郵件的程式設計,郵件傳送功能是基於郵件協議的,常見的電子郵件協議有SMTP(簡單郵件傳輸協議)、POP3(郵局協議)、IMAP(Internet郵件訪問協議),文章主要參考周存傑的《C#網路程式設計例項教程》.這也是最後
C#網路程式設計之---TCP協議的同步通訊(二)
上一篇學習日記C#網路程式設計之--TCP協議(一)中以服務端接受客戶端的請求連線結尾 既然服務端已經與客戶端建立了連線,那麼溝通通道已經打通,載滿資料的小火車就可以彼此傳送和接收了。現在讓我們來看看資料的傳送與接收 先把服務端與客戶端的連線程式碼敲出來 服務端 IPAddress ip = new IP
C# 網路程式設計之webBrowser亂碼問題及解決知識
在使用PHP+MySQL編寫網頁時,曾近就因為顯示中文亂碼”口口口???”困擾我很長時間,沒想到在C#製作瀏覽器或獲取XML頁面時也經常會遇到顯示中文亂碼的問題,可想而知怎樣解決編碼問題
Linux 下 C 網路程式設計之 多執行緒通訊 例項
簡單示例,有不對的地方,歡迎指點。 伺服器端 /* ============================================================================ Name : sockThreadServer
linux c/c++網路程式設計之—select模型
1.select 模型是一個比較傳統的非同步IO模型,我們知道的著名的apache就是基於select模型,而我之前工作過的搜狐暢遊的天龍八部,還有幾款遊戲都是基於select模型。 對於select模型,大多都是說他的缺點,實際上我的觀點有點不一樣,select模型的跨平