一、TCP循環服務器
TCP循環服務器一次只能處理一個客戶端的請求,處理完成後,才能接受下一個客戶端的請求,程序流程如下:
socket(......);//創建套接字 bind(......);//綁定到某端口 listen(......);//監聽客戶端連接 while(1)//循環處理客戶端的請求 { accept(......);//接受一個客戶端連接 while(1)//處理客戶端的請求 { recv(......); process(......); send(......); } close(......);//關閉當前客戶端連接 }
二、UDP循環服務器
UDP循環服務器每次從套接字上讀取一個客戶端的請求並處理,然後將結果返回給客戶機,程序流程如下:
socket(......);//創建套接字 bind(......);//綁定到某端口 while(1)循環處理客戶端的請求 { recvfrom(......); process(......); sendto(......); }
三、並發處理器
並發處理器是指服務器在同一個時刻可以響應多個客戶端的請求,他的思想是每一個客戶端的請求並不由服務器進程直接處理,而是創建一個子進程來處理,這可以彌補TCP循環服務器容易出現某個客戶端獨占服務端的缺陷,程序流程如下:
socket(......);//創建套接字 bind(......);//綁定到某端口 listen(......);//監聽客戶端連接 while(1)//循環處理客戶端的請求 { accept(......);//接受一個客戶端連接 if(fork(......)==0)//創建子進程 { while(1)//處理客戶端的請求 { recv(......); process(......); send(......); } close(......);//關閉當前客戶端的連接 exit(......);//子進程退出 } close(......);//父進程關閉連接套接字,准備接受下一個客戶端連接 }
四、多路復用I/O並發服務器
多路復用I/O並發服務器是為了解決創建子進程帶來的系統資源消耗問題而提出的,前面幾種服務器都是阻塞方式的套接字,使用阻塞方式的套接字,進程的效率比較低,尤其是進行讀寫操作時。我們可以使用fcntl()或ioctl()函數來改變套接字的屬性,將其設置為無阻塞方式,程序流程如下:
socket(......);//創建套接字 bind(......);//綁定到某端口 listen(......);//監聽客戶端連接 while(1)//循環處理客戶端的請求 { FD_SET(......);//設置監聽讀寫文件描述符 switch(select(......))//調用select函數 { case -1://發生錯誤,退出 exit(1); case 0://超時 break; default: if(.....)//新的連接請求建立 { accept(......);//接受一個客戶端連接 FD_SET(......);//將連接套接字加入到監聽文件描述符集合中 } else//可讀寫的為一個已經創建過連接的描述符 { ......//讀寫套接字 } } }