tcp套接字程式設計經常使用在客戶/伺服器程式設計模型(簡稱c/s模型)中,c/s模型根據複雜度分為簡單的客戶/伺服器模型和複雜的客戶/伺服器模型。c/s簡單客戶/伺服器模型是一對一關係,乙個伺服器端某一時間段內只對應處理乙個客戶端的請求,迭代伺服器模型屬於此模型。c/s複雜伺服器模型是一對多關係,乙個伺服器端某一時間段內對應處理多個客戶端的請求,併發伺服器模型屬於此模型。迭代伺服器模型和併發伺服器模型是socket程式設計中最常見使用的兩種程式設計模型,圖18-5畫出兩種模型服務端的處理流程。
18-5 迭代伺服器&併發伺服器圖
1. tcp套接字程式設計模型圖
圖18-6是tcp套接字程式設計模型圖,畫出了客戶端與服務端的程式設計模型和流程。此模型不僅適合迭代伺服器,也適合併發伺服器,兩者實現流程類似,只不過併發伺服器接收客戶請求(accept)後會fork子程序,由子程序處理客戶端的請求。
圖18-6 tcp套接字程式設計模型圖
2. tcp程式設計流程說明
(1) 伺服器端程式設計流程
tcp伺服器端程式設計流程如下:
① 建立套接字;
② 繫結套接字;
③ 設定套接字為監聽模式,進入被動接受連線狀態;
④ 接受請求,建立連線;
⑤ 讀寫資料;
⑥ 終止連線。
(2) tcp客戶端程式設計流程
tcp客戶端程式設計流程如下:
① 建立套接字;
② 與遠端伺服器建立連線;
③ 讀寫資料;
④ 終止連線。
(3) tcp伺服器三種異常情況
tcp伺服器有三種異常情況,分別為伺服器主機崩潰、伺服器主機崩潰後重啟、伺服器主機關機。
在伺服器主機崩潰的情況下,已有的網路連線上發不出任何東西。此時應用程式發出資料後,會阻塞於套接字的讀取回應。由於伺服器主機崩潰,此時客戶tcp會持續重傳資料分節,試圖從伺服器接收乙個ack,重傳12次(源自berkeley的實現)後,客戶tcp最終選擇放棄,返回給應用經常乙個etimedout錯誤;或者是因為中間路由器判定伺服器主機不可達,則返回乙個目的地不可達的icmp訊息響應,其錯誤**為ehostunreach或enetunreach。另外說明的是,通過設定套接字選項可以更改tcp持續重傳等待的超時時間。
在伺服器主機崩潰後重啟的情況下,如果客戶在主機崩潰重啟前不主動傳送資料,那麼客戶是不會知道伺服器已崩潰。在伺服器重啟後,客戶向伺服器傳送乙個資料分節;由於伺服器重啟後丟失了以前的連線資訊(儘管在服務埠上有程序監聽,但連線套接字所在的埠無程序等待),因此導致伺服器主機的tcp響應rst;當客戶tcp收到rst,向客戶返回錯誤econnreset。如果客戶對伺服器的崩潰情況很關心,即使客戶不主動傳送資料也這樣,這需要進行相關設定(如設定套介面選項so_keepalive或某些客戶/伺服器心跳函式)。
當伺服器主機關機的情況下,由於init程序給所有執行的程序發訊號sigterm,這時伺服器程式可以捕獲該訊號,並在訊號處理程式中正常關閉網路連線。如果伺服器程式忽略了sigterm訊號,則init程序會等待一段固定的時間(通常是5s~20s),然後給所有還在執行的程式發訊號sigkill。伺服器將由訊號sigkill終止,其終止時,所有開啟的描述字被關閉,這導致向客戶傳送fin分節,客戶收到fin分節後,能推斷出伺服器將終止服務。
3. 讀寫函式的封裝
(1)網路資料讀寫說明
在網路程式中,向套接字檔案描述符寫時有以下兩種可能:
① write的返回值大於0,表示寫了部分或者是全部的資料。
② 返回的值小於0,此時寫出現了錯誤,需要根據錯誤型別來處理。如果錯誤號為eintr,則為中斷引起,可以忽略進行繼續寫操作;如果是其他錯誤號,則表示網路連線出現了問題(可能對方關閉了連線),則需報錯退出。
像向套接字檔案描述符寫資料一樣,讀也有兩種可能:
① read的返回值大於0,表示讀了部分或者是全部的資料。
② 返回的值小於0,此時讀出現了錯誤,需要根據錯誤型別來處理。如果錯誤號為eintr,則為中斷引起,可以忽略進行繼續讀操作;如果是其他錯誤號,則表示網路連線出現了問題,則需報錯退出。
(2)讀寫函式的封裝
為了讀寫函式更加健壯,更加易用,需要對讀寫函式進行封裝。tcpio.c源**中readn函式對read函式進行了封裝,writen函式對write進行了封裝。
tcpio.c源**如下:
#include
#include
#include
#include
int readn(int fd,void *buffer,int length)
int bytes_left;
int bytes_read;
char *ptr;
bytes_left=length;
ptr=buffer ;
while(bytes_left>0)
bytes_read=read(fd,ptr,bytes_left);
if(bytes_read<0)
if(errno==eintr)
bytes_read=0;
else
return(-1);
else if(bytes_read==0)
break;
bytes_left-=bytes_read;
ptr+=bytes_read;
return(length-bytes_left);
int writen(int fd,void *buffer,int length)
int bytes_left;
int written_bytes;
char *ptr;
ptr=buffer;
bytes_left=length;
while(bytes_left>0)
written_bytes=write(fd,ptr,bytes_left);
if(written_bytes<0)
if(errno==eintr) /* 錯誤由中斷引起,可以繼續寫*/
written_bytes=0;
else /*其他錯誤,報錯退出*/
return(-1);
bytes_left-=written_bytes;
ptr+=written_bytes;
return(0);
摘錄自《深入淺出linux工具與程式設計》
TCP套接字程式設計模型
tcp套接字程式設計經常使用在客戶 伺服器程式設計模型 簡稱c s模型 中,c s模型根據複雜度分為簡單的客戶 伺服器模型和複雜的客戶 伺服器模型。c s簡單客戶 伺服器模型是一對一關係,乙個伺服器端某一時間段內只對應處理乙個客戶端的請求,迭代伺服器模型 屬於此模型。c s複雜伺服器模型是一對多關係...
tcp套接字程式設計模型
用下面的一張圖可以清楚表示 下面的python實現也很清晰 server def tcplink sock,addr print accept new connection from s s.addr sock.send welcome while true data sock.recv 1024 ...
TCP套接字程式設計
網路程式設計又稱為套接字程式設計,為了與遠端計算機進行資料傳輸,需要連線到網際網路,而程式設計中的 套接字 就是用來連線該網路的工具。它本身具有連線的含義,還可以表示為兩台計算機之間的網路連線。4.呼叫accept函式受理連線請求 基於tcp的服務端 客戶端 tcp伺服器端預設函式呼叫順序 sock...