1,TCP循環服務器:
首先,TCP服務器接受壹個客戶端的連接請求,處理連接請求,完成這個客戶端的所有請求後斷開連接,然後接受下壹個客戶端的請求。創建TCP環路服務器的算法如下:
復制代碼代碼如下:
插座(……);//創建TCP套接字
bind(……);//綁定已識別的端口號
聽(……);//偵聽客戶端連接
而(1) //開始循環接收客戶端連接。
{
接受(……);//接收當前客戶端的連接。
while(1)
{//處理當前客戶端的請求。
讀(……);
過程(……);
寫(……);
}
關閉(……);//關閉當前客戶端連接,準備接收下壹個客戶端連接。
}
TCP循環服務器壹次只處理壹個客戶端的請求。如果壹個客戶端占用了服務器,其他客戶端的連接請求將得不到及時的響應。因此,TCP服務器很少使用循環服務器模型。
2.TCP並發服務器:
並發服務器的思想是每個客戶端的請求不是由服務器主進程直接處理,而是由服務器主進程創建壹個子進程來處理。創建TCP並發服務器的算法如下:
復制代碼代碼如下:
插座(……);//創建TCP套接字
bind(……);//綁定已識別的端口號
聽(……);//偵聽客戶端連接
而(1) //從接收客戶端開始循環接收。
{
接受(……);//從客戶端接收連接
If (fork(...)= = 0)//創建子進程。
{
while(1)
{//子進程處理客戶端的連接。
讀(……);
過程(……);
寫(……);
}
關閉(……);//關閉子進程處理的客戶端連接。
退出(……);//終止子進程
}
關閉(……);//父進程關閉連接套接字描述符,並準備接收下壹個客戶端連接。
}
TCP並發服務器可以解決TCP循環服務器客戶端獨占服務器的情況。但同時也帶來了壹個很大的問題,就是響應客戶端的請求,服務器要創建壹個子進程來處理,而創建子進程是壹個非常耗費資源的操作。
3.UDP循環服務器:
UDP服務器每次從套接字讀取壹個客戶端的數據報請求,處理收到的UDP數據報,然後將結果返回給客戶端。創建UDP環路服務器的算法如下:
1插座(……);//創建數據報類型套接字2bind(...);//短標語3 while(1) //開始接收客戶端的連接4 {//接收並處理UDP數據報5 recvfrom(...)的客戶端;6流程(……);7 send to(……);//準備接收下壹個客戶端數據報8}
消除行號
因為UDP不是面向連接的,所以沒有客戶端可以獨占服務器。只要這個過程不是壹個無限循環,服務器總是可以處理每個客戶端的請求。
當數據報流量過大時,UDP循環服務器可能會因為處理任務繁重而丟失數據報。但是UDP協議本身並不能保證數據報的可靠到達,所以UDP協議允許數據報丟失。
鑒於以上兩點,壹般UDP服務器采用循環模式。4.UDP並發服務器將並發的概念應用到UDP中得到壹個並發UDP服務器,與並發TCP服務器模型相同,創建壹個子進程來處理。
創建UDP並發服務器的算法如下:
復制代碼代碼如下:
插座(……);//創建數據報類型的套接字。
bind(……);//國家認可的短標語
While(1) //開始接收來自客戶端的連接。
{//接收和處理來自客戶端的UDP數據報。
recvfrom(……);
If (fork(...)= = 0)//創建子進程。
{
process(……);
send to(……);
}
}
除非服務器需要很長時間來處理客戶端的請求,否則人們很少使用這種UDP並發服務器模型。
4.多路輸入輸出並發服務器:
創建子進程會帶來大量的系統資源消耗。為了解決這壹問題,采用了具有多路復用I/O模型的並發服務器。使用select函數創建具有多路復用I/O模型的並發服務器的算法如下:
初始化(套接字、綁定、監聽);
復制代碼代碼如下:
while(1)
{
設置文件描述符(FD_*)用於監聽和讀取;
呼叫選擇;
如果監聽套接字準備好了,就建立新的連接請求。
{
建立連接(接受);
將其添加到監控文件描述符中;
}
否則,描述是壹個連接的描述符。
{
執行操作(讀或寫);
}
復用I/O可以解決資源受限的問題。這個模型實際上使用了TCP上的UDP循環模型。這樣也會帶來壹些問題,比如因為服務器依次處理客戶的請求,可能會造成朋友的客戶等待時間長。