使用empoll實現讀寫和推送伺服器 一

2021-08-21 20:12:36 字數 2530 閱讀 1947

linux下的服務大多都是epoll,網上有很多都是requset-response型別的伺服器; 自己專案中有推送的需要,所以自己也做了個,另外我閱讀了epoll寫操作事件觸發機制感覺寫得很全,自己也測試過,寫了個server,與大家分享。

為了好濱示推送,我把它與qt專案結合了,qt只是為了產生推送的訊息,其它全為純c++**。epoll的監聽是乙個死迴圈,我定義了如下介面。

#ifndef loop_h

#define loop_h

class loop

protected:

virtual void _run() = 0;//迴圈函式

};#endif // loop_h

#ifndef epollloop_h

#define epollloop_h

#include "loop.h"

#include "epollstream.h"

#include #include #include class epollserver;

class epollloop : public loop

;#endif // epollloop_h

#include "epollloop.h"

#include #include #include #include #include "epollserver.h"

#include #include #include epollloop::epollloop()

void epollloop::_run() //啟動epll監聽執行緒函式,並與主線程分離

void epollloop::_initialize() //建立epoll控制代碼

_run();

}void epollloop::_epollthread()

qdebug() << "event fd count" << nfds;

for(int i = 0; i < nfds; i++)

epollstreamptr stream = _streams[fd];

if(events[i].events & epollin)

}if(events[i].events & epollout)}}

}int32_t epollloop::_accept(int32_t eventfd, int32_t listenfd) //通過map對映呼叫server介面,處理新連線,reactor模式的典型應用

}epollloop *epollloop::get()

epollloop::~epollloop()

void epollloop::addserver(int socket, epollserver *server));}

void epollloop::addstream(epollstreamptr stream)

void epollloop::writemsg(std::string &bytes, std::vectorfds) //通過epoll主動推送訊息,用於在客戶端沒有請求時

}else}}

}}int32_t epollloop::addepollevents(int32_t events, int32_t fd) //新增監聽事件

int32_t epollloop::modifyepollevents(int32_t events, int32_t fd) //更改乙個已存在事件的監聽事件

對於讀取操作:

(1) 當buffer由不可讀狀態變為可讀的時候,即由空變為不空的時候。

(2) 當有新資料到達時,即buffer中的待讀內容變多的時候。

(3) 當buffer中有資料可讀(即buffer不空)且使用者對相應fd進行epoll_mod in事件時。

對於寫操作:

(1) 當buffer由不可寫變為可寫的時候,即由滿狀態變為不滿狀態的時候。

(2) 當有舊資料被傳送走時,即buffer中待寫的內容變少得時候。

(3) 當buffer中有可寫空間(即buffer不滿)且使用者對相應fd進行epoll_mod out事件時。

以下為推送截圖

當初始化時,緩衝區為空可寫,會觸發乙個寫事件

以下為接收截圖

接收的話,我沒有做其它操作只是在ide裡面列印出來了。工程會在其它模組講完之後,上傳,有意向的朋友可以先裝好linux的qt我用的是qt5.9.3,按照要求qt5以上就可以了。

在這個例子中,客戶端連線的讀寫以及推送都是在epoll的執行緒中執行,之前用過多執行緒讀寫,但有競爭問題;還是選擇了這種,畢竟書上也是這樣的;另外,我們還需要對收到的客戶端訊息做業務處理如果是耗時操作,就要考慮執行緒池了,socket的讀寫放在乙個執行緒中不容易問題;處理可以放在其它執行緒中,。

使用Jpush 極光推送 實現推送功能

農曆猴年最後一篇文章,在寫前先寫一段話,我覺得挺好的,2017年要努力做到 學會忍耐,因為事已成現實自己無法改變 學會說不,因為做不到的事不要強求 學會適應,因為任何條件下都要生存 學會知而不言,因為言多必失 學會拿得起放得下,以為只要這樣才會能重新開始新的起點 做不了決定的時候,讓時間幫你決定,如...

使用Websocket實現訊息推送(上)

聯絡客服功能在專案中非常難避免。一般有以下三種實現方式 第一種方式,最low的。實現簡單。可是浪費使用者流量 另外一種方式,接入簡單,功能強大,可是可能須要一定的成本 比方付費 第三種方式,須要一定的開發成本 伺服器託管費用忽略 websocket一種在單個 tcp 連線上進行全雙工通訊的協議。we...

實現reentrantlock和讀寫鎖

1 可以手動實現乙個類似reentrantlock的工具,首先要維護乙個state的標誌,代表當前是否有執行緒已經使用資源。執行緒lock的時候,會用cas給state加1,其他執行緒檢測狀態。另外需要維護乙個等待佇列,爭奪不到資源的執行緒統一掛起 park 等執行緒unlock的時候,標誌減為0,...