epoll 多路復用模型
套接字的阻塞和非阻塞模式
套接字選項
套接字選項詳細規定了套接字的屬性,影響socket的各項操作。我們可以通過setsockopt
函 數和getsockopt
函式愉快的設定和獲取socket的屬性。
首先來看一下setsockopt函式:
setsockopt函式
返回值:成功返回0,失敗返回-1
getsockopt函式
返回值:成功返回0,失敗返回-1
套接字api層常用的socket屬性
名稱選項
數值型別
so_broadcast
允許傳送廣播資料
intso_debug
允許除錯
intso_dontroute
不查詢路由
intso_error
獲得套接字錯誤
intso_keepalive
保持連線
intso_linger
延遲關閉連線
struct linger
so_oobinline
帶外資料放入正常資料流
intso_rcvbuf
接收緩衝區大小
intso_sndbuf
傳送緩衝區大小
intso_rcvlowat
接收緩衝區下限
intso_sndlowat
傳送緩衝區下限
intso_rcvtimeo
接收超時
struct timeval
so_sndtimeo
傳送超時
struct timeval
so_reuseaddr
允許重用本地位址和埠
intso_type
獲得套接字型別
intso_bsdcompat
與 bsd 系統相容
intepoll多路復用模型是linux中特有的,相比之前學過的select,參見linux環境:c程式設計檔案操作,epoll更加靈活,效能也更出色,支援水平觸發和邊緣觸發兩種觸發模式。
介面函式
epoll模型由三個函式組成:
int epoll_create(int size);
//建立乙個epoll例項
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);//
新增監控的套接字
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
//返回i/o就緒的套接字
函式原理:
//聯合體,事件觸發時返回的資訊,一般填對應的檔案描述符,來表示該事件由誰觸發
typedef union epoll_data epoll_data_t;
struct epoll_event
;
events可以是以下幾個巨集的集合:
epollin:表示對應的檔案描述符可以讀(包括對端socket正常關閉);
epollout:表示對應的檔案描述符可以寫;
epollpri:表示對應的檔案描述符有緊急的資料可讀(這裡應該表示有帶外資料到來);
epollerr:表示對應的檔案描述符發生錯誤;
epollhup:表示對應的檔案描述符被結束通話;
epollet: 將epoll設為邊緣觸發(edge triggered)模式,這是相對於水平觸發(level triggered)來說的。
epolloneshot:只監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到epoll佇列裡
epoll_wait函式返回就緒的套接字列表,第乙個引數是epoll例項,第二個引數是返回的結構體陣列,每個元素對應乙個套接字的資訊,第三個列表是該結構體陣列的容量, 值不能大於epoll例項中就緒列表的最大長度,第四個引數是監視計時器(毫秒,0會立即返回,-1將不確定,也有說法說是永久阻塞)。該函式返回需要處理的事件數目,如返回0表示已超時。
觸發模式
lt模式:工作邏輯和select一致,只要緩衝區中存在沒有讀寫的資料就一直觸發。
et模式:僅當緩衝區狀態發生變化的時候才獲得通知。這裡的狀態的變化並不包括緩衝區中還有未處理的資料,也就是說,如果要採用et模式,需要一直read/write直到出錯為止,否則未讀寫的資料就會丟失。
套接字的預設狀態是阻塞狀態,即在進行bind,read,write,send,recv,connect,accept等操作時,如果沒有輸入,則會阻塞程序。
設定非阻塞套接字
可以通過設定檔案描述符的標誌位來把套接字設定為非阻塞模式。
用到以下函式:
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
fcntl函式可以獲取或者設定檔案的標誌位,fd是檔案描述符,cmd是命令,如果有第三個引數則是命令的引數。
通過以下**可以設定非阻塞套接字
//獲取當前檔案的檔案描述標誌位
int status=fcntl(fd,f_getfl);
//將該標誌位或上非阻塞標誌
status=status|o_nonblock;
//重新設定檔案的標誌位
fcntl(fd,f_setfl,status);
阻塞和非阻塞的區別
套接字呼叫可分為四種
非阻塞:
輸出操作,包括write,writev,send,sendto,sendmsg
阻塞: 非阻塞:
接收外來連線,即用於accept函式
發起外出連線,即用於tcp的connect函式。
Python 網路通訊程式設計之udp通訊程式設計
import socket 1.建立例項,即資料報套接字 server socket.socket socket.af inet,socket.sock dgram 2.繫結位址,進行監聽 server.bind 127.0.0.1 3120 3.收發訊息 while true data serve...
C 網路通訊程式設計
1 wcf wcf是rpc的一套框架和機制 系列文章 我的wcf之旅 1 系列文章列表 2 其中的入門 建立乙個簡單的wcf程式 2 http通訊 1 http協議簡介 這裡有比較詳細的入門級介紹 這個除了基本的類外,還有網路抓取的框架,是收費的。此外,他還有關於這些原理還程式設計的諸多介紹文章,都...
C 網路通訊
c 網路通訊 一 伺服器端程式 10.17 1.建立伺服器端socket 1 使用socket類 建立伺服器socket物件 socket objs new socket 引數 使用ipendpoint類設定伺服器ip位址和埠號 或使用dns類 ipaddress serip ipaddress.p...