IO模型與TCP併發伺服器

2021-07-16 03:57:57 字數 2681 閱讀 1858

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...