TCP套接字程式設計模型

2021-05-26 11:51:03 字數 3134 閱讀 8537

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