io模型與tcp併發伺服器
io模型
1、阻塞io
2、非阻塞io
3、io多路復用
4、訊號驅動io
1、阻塞io ===》最常用 預設設定
io: scanf()/printf() ====>預設的io裝置
fgetc()/fputc() ====》標準io
fgets()/fputs()
fread()/fwrite()
read()/write() ====》檔案io,pipe fifo
recv()/send() ====>tcp socket
recfrom()/sendto() ===>udp socket
scanf fgetc fgets fread read recv recvfrom ==>阻塞等待
2、非阻塞io ===》在阻塞io的基礎上調整其為不再阻塞等待。
2.1 在程式開始階段調整檔案的開啟方式為非阻塞:
===》open()===>fifo()的同步。
open("fifo",o_rdonly|o_nonblock);
====>read() 不再阻塞。
2.2 在程式執行階段調整檔案的執行方式為非阻塞:
===》fcntl() ===>動態調整檔案的阻塞屬性
#include
#include
int fcntl(int fd, int cmd, ... /* arg */ );
功能:修改指定檔案的屬性資訊。
引數:fd 要調整的檔案描述符
cmd 要調整的檔案屬性巨集名稱
... 可變長的屬性值引數。
返回值:成功 不一定,看cmd
失敗 -1;
eg:修改檔案的非阻塞屬性:
int flag ;
flag = fcntl(fd,f_getfl,0); ///獲取fd檔案的預設屬性到flag變數中。
flag = flag | o_nonblock; ///將變數的值調整並新增非阻塞屬性
fcntl(fd,f_setfl,flag); ///將新屬性flag設定到fd對應的檔案生效。
以上**執行後的阻塞io將變成非阻塞方式。
練習:編寫fifo測試函式,完成fcntl控制的非阻塞方式讀寫。
修改之前的tcp,udp程式用fcntl測試其非阻塞特性。
如果是recv()/recvfrom()===》引數flags == msg_dontwait
如果是read() ====>fcntl()
3、io 多路復用 ===》併發伺服器 ===》tcp協議
基於tcp協議的多並負伺服器模型:
1、簡單迴圈伺服器
while(1)
特點:可以多併發的接入多個客戶端的資訊。
缺點:資料通訊過程短,客戶端只能一次有效。
實時性效果差。
2、fork迴圈伺服器===>每次有鏈結則fork乙個子程序為該
鏈結處理通訊過程,父程序繼續等待新鏈結。
while(1)
if(pid < 0)
waitpid()
}特點:可以完成多個程序的實時互動,資訊的完整性可以保證。
缺點:**資源不方便,每次fork 占用系統資源多。
可能出現殭屍程序
驗證的問題:
1、如何**所有子程序資源
2、如何用壓力測試證明伺服器的負載。
3、select迴圈伺服器 ===> 用select函式來動態檢測有資料流動的檔案描述符
#include
#include
#include
#include
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
功能:完成指定描述符集合中有效描述符的動態檢測。
該函式具有阻塞等待功能,在函式執行完畢後
目標測試集合中將只保留最後有資料的描述符。
readfds 唯讀描述符集
writefds 只寫描述符集
exceptfds 異常描述符集
以上三個引數都是 fd_set * 的描述符集合型別
timeout 檢測超時 如果是null表示一直檢測不超時 。
返回值:成功 0
失敗 -1
為了配合select函式執行,有如下巨集函式:
void fd_clr(int fd, fd_set *set);
功能:將指定的set集合中編號為fd的描述符號刪除。
int fd_isset(int fd, fd_set *set);
功能:判斷值為fd的描述符是否在set集合中,
如果在則返回真,否則返回假。
void fd_set(int fd, fd_set *set);
功能:將指定的fd描述符,新增到set集合中。
void fd_zero(fd_set *set);
功能:將指定的set集合中所有描述符刪除。
作業:使用以上任意乙個併發伺服器模型,完成如下功能:
可以向伺服器傳送乙個訊息,並在伺服器端列印
輸出該訊息的**ip+port。同時將所有的連線終端
的個數統計出來。
TCP併發伺服器模型(一)
本篇敘述的tcp併發伺服器模型如下圖所示 伺服器建立並繫結套接字後fork出幾個子程序,子程序中分別進行accept 該函式為阻塞函式 recv 處理資料然後再次acept,這樣迴圈下去。所有客戶端發來的資訊都是直接由子程序處理。例程 如下,在處理客戶端請求之前,伺服器先fork了3個子程序,然後將...
TCP的高併發伺服器模型
單客戶端單程序,統一accept 原型介紹 此併發伺服器模型並不預先分叉程序,而是主程序統一處理客戶端的連線,當客戶端的請求到達時,才臨時fork 程序,由子程序處理客戶端請求。利用socket 函式建立套接字,呼叫bind 函式繫結位址,呼叫listen 函式來監聽佇列長度,然後進入主處理過程,等...
TCP併發伺服器
int main int recvcnt 0 struct sockaddr in sock server struct sockaddr in sock client int len sizeof struct sockaddr socketfd socket pf inet,sock strea...