[Boost] ASIO學習筆記:network basic– UDP Server
UDP Server跟TCP Server不同,它是屬於connectionless的技術,因此不需要acceptor去跟client建立連線的步驟。我們只需要利用socket去bind特定的port後,就可以接收到資料。 一個Sync socket的流程如下,圖片引用自此: 在ASIO中的Server端程式碼: #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> #include <iostream> #include <string> #include <boost/thread.hpp> using namespace std; void main(){ boost::system::error_code ec; boost::shared_ptr<boost::asio::io_service> io_service(new boost::asio::io_service); boost::shared_ptr<boost::asio::io_service::strand> strand(new boost::asio::io_service::strand(*io_service)); // boost::shared_ptr< boost::asio::io_service::work > work(new boost::asio::io_service::work( *io_service )); try{ … Continued
[Boost] ASIO學習筆記:network basic– TCP Server
在上一篇[Boost] ASIO學習筆記:network basic – client有展示了該怎麼撰寫一個client去連接一個遠端的Server,而在本篇,將會接著介紹怎麼利用ASIO撰寫一個Server來處理與client端的連接。 首先在Server端開始運行之前,最重要的事便是決定要與哪個port綁定並監聽是否有資料傳送進來。只是,到底什麼是port呢?port是範圍定在0~65535之間的號碼,為Client跟Server之間連接的管道。打個比喻來說:如果ip是電話號碼的話,那麼port便是一個公司(Server)的分機號碼。port所定義的,是Client要打哪個分機號碼才能得公司(Server)所提供的服務。 其中: 0~1023為公認埠(Well Known Ports),通常用於某些特定的系統程序或者是常用的網路協定上。例如80為http、21為ftp、23為telnet…等等。 1024~49151為註冊埠(Registered Ports):理論上要使用該port來提供服務的公司要跟IANA是出申請,但實際上我們也常常拿來做動態或私人用途。 49152~65535為動態和/或私有埠(Dynamic and/or Private Ports):通常是拿來當作臨時或特定客製化的需求時使用。 其實,在撰寫程式的時候,我們可以去監聽任何的port,下圖為TCP Server操作的流程圖(下圖引自wiki,我們可以看到ASIO完全遵照Berkeley sockets API進行封裝): 以下為一個最簡單監聽port 12345的serve程式: #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/bind.hpp> #include <iostream> #include <string> #include <boost/thread.hpp> using namespace std; void onAcceptEvent(boost::system::error_code ec, … Continued
[分享] 如何將windows live writer的本地存檔同步到dropbox的資料夾下
雖然windows live writer是一個很強大的blog編寫工具,但相信有很多人都有想要將撰寫的文章同步更新到雲端硬碟下,可是程式卻找不到任何可以進行設定的地方。這時候,我們就必須要繞一下路,利用建立『捷徑』的方式,將存檔的路徑指向我們所希望的任何地方。如果要要同步到Dropbox下,則步驟如下: 1.將原本C:\Users\dorgonman\Documents\My Weblog Posts下的資料夾砍掉,其為原本windows live writer所設定的存檔路徑。 2.建立資料夾在C:\workspace\Dropbox\My Weblog Posts下 3. 之後用系統管理員身份執行cmd,執行以下指令: mklink /D “C:\Users\dorgonman\Documents\My Weblog Posts” “C:\workspace\Dropbox\My Weblog Posts” 如果出現:已建立 xxx的符號連結,的話便表示我們的操作成功
[Boost] ASIO學習筆記:network basic – client
對於網路程式設計而言,不外乎是server或者是client程式這二種。 而怎麼讓二台遠端的電腦透過網路溝通的程式設計,稱作socket programming。 現在就讓我們先從最基本的client端連接到遠端server的程式開始: #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <iostream> #include <string> using namespace std; int main( int argc, char * argv[] ) { boost::shared_ptr< boost::asio::io_service > io_service(new boost::asio::io_service); boost::asio::ip::tcp::socket sock( *io_service ); boost::asio::ip::tcp::resolver resolver(*io_service); boost::asio::ip::tcp::resolver::query query( “www.yahoo.com.tw”, “80”); boost::asio::ip::tcp::resolver::iterator … Continued
[Boost] ASIO學習筆記:使用strand來serializing thread
[insert page=’151′ display=’link’],我們知道在多條thread的程式設計中,對於執行的結果我們是無法預期的。雖然使用mutex可以保證thread-safety,但卻無法保證工作能夠照我們所期望的順序執行。 在boost ASIO中提供了strand來解決既能保證thread-safety又能夠讓工作的順序能夠依照post的順序執行。執行並觀察以下的程式結果: boost::mutex global_stream_lock; void WorkerThread( boost::shared_ptr< boost::asio::io_service > io_service ){ global_stream_lock.lock(); std::cout < < “[” << boost::this_thread::get_id() << “] Thread Start” << std::endl; global_stream_lock.unlock(); io_service->run(); global_stream_lock.lock(); std::cout < < “[” << boost::this_thread::get_id() << “] Thread Finish” … Continued
[Boost] ASIO學習筆記:post and dispatch
對於io_service之中,最重要的莫過於post跟dispatch這二個功能。到底這二個功能有何異同呢? post:指的是將一個工作加入Completion Event Queue裡面dispatch:若是在被run()或poll()所回呼的handler,則馬上執行指派的工作,若是在main()的線程中,則效力與post相同。 試著執行以下程式可以看到二個函式的不同: boost::mutex global_stream_lock; void Dispatch( int x ){ global_stream_lock.lock(); std::cout < < “[” << boost::this_thread::get_id() << “] ” << __FUNCTION__ << ” x = ” << x << std::endl; global_stream_lock.unlock(); } void Post( int x ){ … Continued
[boost]ASIO學習筆記:Sync/Async、Blocking/Non-Blocking IO
關於四種名詞的詳細內容可以參閱本篇連結 其實這四個名詞在概念上有一些微妙的差別,Sync/Async IO的差別在於程式是否要去等待OS的IO操作結束:在boost中是指io_service選用了run()或者是poll(),會進行kernel context switch到OS kernel來運行。而Blocking/Non-Blocking則是指我們是否要等待程式執行流程中的IO結束才能繼續執行,主要是由application來實作、設計執行的機制。 其實一個程式是不是Sync/Asyn或blocking/non-blocking,其實看的是一段程式碼或者是一個function 通常如果該段程式碼包含while迴圈來判斷某個檔案是狀態,那麼就是blocking,但如果這時候又程式thread來分配該任務的執行,那麼就是non-blocking。 在non-blocking的程式中,如果有牽扯到檔案的讀寫問題,那麼我們就必須在程式中撰寫一些機制去確認該檔案是如已經可以寫入,以必免造成race condition的情況。通常依照不同的作業系統會使用poll、select、epoll、iocp等機制。 關於poll、select、epoll等分別請參閱本篇 在boost::ASIO中,由於為了要達成跨平台,因此在背後實作了Proactor模式來隱藏細節,並以Reactor來實作不同平台的機制。我們可以利用以下的程式碼印出我們的作業系統所採用的是那一種: #include <iostream> #include <string> #include <boost/asio.hpp> int main() { std::string output; #if defined(BOOST_ASIO_HAS_IOCP) output = “iocp” ; #elif defined(BOOST_ASIO_HAS_EPOLL) output = “epoll” ; #elif defined(BOOST_ASIO_HAS_KQUEUE) output = “kqueue” … Continued
[Boost] ASIO學習筆記:thread及Synchronization
我們知道,我們無法預測thread執行的先後,這代表的是任何一個thread都有可以在任何的時間點從CPU上取得操作權。這不僅會造成cout時文字無法連續,同時在操作資料時,最害怕的情形是『同時』有多個thread去對『同一個資料』做更改,因為他會造成運算結果的錯誤。這個特性,在電腦科學裡面稱作race condition,進而導致了需要保證thread-safety的問題。 在boost裡提供了mutex機制來解決(Critical Section Problem) 一個簡單的demo: #include <boost/thread.hpp> #include <iostream> void wait(int seconds) { boost::this_thread::sleep(boost::posix_time::seconds(seconds)); } boost::mutex mutex; int gValue = 0; void thread(int i) { wait(1); mutex.lock(); gValue = gValue + i; std::cout < < “Thread :” << boost::this_thread::get_id() … Continued
[Boost] ASIO學習筆記:bind and ASIO
boost::bind的功用,主要是將function變成function object(functor)來當成參數傳送,其目的,最主要是用來實現系統callback的功能。以下為一個簡單的小程式: #include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include <iostream> using namespace std; boost::asio::io_service io_service; void WorkerThread(int x){ std::cout < < “Thread Start:” << x << endl; io_service.run(); std::cout << “Thread Finish:” << x << endl; } int main( int … Continued
[C++][範例]windows programming:window lock
關於Windows programming的基本觀念,可以參閱這裡。 這篇並不會解釋太多windows programming上的觀念,純粹只是分享過去的程式作品。在這裡可以看到的是,我怎麼對window創建的程序進行封裝以及對於loop迴圈的設計方法。本程式在執行之後會跳出一個白色的視窗佔住整個營幕並鎖定其他操作,按下F4可以逃出鎖定,其中包含以下幾個檔案:WinPro.hWinPro.cppmain.cpp:包含主程式main(),為程式的進入點 WinPro.h: #pragma once #include <iostream> #include <windows.h> #include <stdlib.h> using namespace std; #ifndef WIN_PRO #define WIN_PRO class WinPro { public: WinPro(void); ~WinPro(void); public://初始函式 bool init(); int start(int nCmdShow); public://靜態視窗函式回傳true代表結束迴圈,以正常方式離開程式 static bool frameFunc(); public://功能函式 void lockWindows(bool bLOCK); … Continued