linux socket程式設計相關問題

2021-08-27 01:15:04 字數 3186 閱讀 9110

1.connect函式響應中斷返回後仍然回到函式的呼叫。實踐證明,對於乙個非阻塞的socket,如果在呼叫connect函式時,如果發生中斷,這函式響應中斷,但當中斷返回時,繼續connect函式的呼叫,直到connect超時失敗或接收到錯誤icmp包或連線成功

2.accept()

如果偵聽程序是非阻塞模式工作,當呼叫accept()函式接收來自客戶端的請求後,返回的socket套接字,預設為阻塞的工作模式。

一、阻塞模型

可能發生阻塞的套介面呼叫分為四種:

1>.輸入操作:read、readv、recv、recvfrom和recvmsg函式

2>.輸出操作:write、writev、send、sendto和sendmsg函式

3>.接收外來連線:accept()函式

4>.初始化外出的連線:connect()函式

二、i/o模型

1.阻塞i/o

2.非阻塞i/o

3.i/o復用(select函式)

4.訊號驅動i/o(sigio)

5.非同步i/o

三、i/o復用模型的應用場合

1.當客戶處理多個描述字時(一般是互動式輸入和網路套介面),必須使用i/o復用。

2.乙個客戶同時處理多個套介面

3.如果乙個tcp伺服器既要處理偵聽套介面,又要處理已連線套介面,一般也要用到i/o復用。

4.如果乙個伺服器既要處理tcp,又要處理udp,一般也要使用i/o復用。

5.如果乙個伺服器要處理多個服務或者多個協議(inetd守護程序)。

四、拒絕服務型攻擊

伺服器某乙個時刻阻塞於只處理單個客戶,而不能處理其他客戶的需求,這就導致了拒絕服務型攻擊,可能的解決辦法是:(a)使用非阻塞i/o模型;(b)讓每個客戶由單獨的控制線程提供服務(例如,建立子程序或執行緒來為每個客戶提供服務);(c)對i/o操作設定超時。

五、connect()函式

1.阻塞模式

客戶端呼叫connect()函式將激發tcp的三路握手過程,但僅在連線建立成功或出錯時才返回。返回的錯誤可能有以下幾種情況:

1>.如果tcp客戶端沒有接收到syn分節的響應,則返回etimedout,阻塞模式的超時時間在75秒(4.4bsd核心)到幾分鐘之間。

2>.如果對客戶的syn的響應時rst,則表明該伺服器主機在我們指定的埠上沒有程序在等待與之連線(例如伺服器程序也許沒有啟動),這稱為硬錯,客戶一接收到rst,馬上就返回錯誤econnrefused.

3>.如果某客戶發出的syn在中間的路由器上引發了乙個目的地不可達icmp錯誤,多次嘗試傳送失敗後返回錯誤號為ehostunreach或enetunreach.

附加:產生rst的三種情況,一是syn到達某埠但此埠上沒有正在偵聽的伺服器、二是tcp想取消乙個已有連線、三是tcp接收了乙個根本不存在的連線上的分節。

2.非阻塞模式

採用非阻塞的工作模式要考慮一下兩種情況:

1>.如果是連線本機,則呼叫connect()函式會立刻建立。

2>.如果伺服器是網路中的使用者,則呼叫connect()函式需要從幾個毫秒的區域網到幾百毫秒或幾秒的廣域網。並且函式會立刻返回einprocess錯誤,但tcp通訊的三路握手過程正在進行,所以可以使用select函式來檢查這個連線是否建立成功。

1>.當連線成功建立時,描述字變成可寫。

2>.當連線建立出錯時,描述字變成即可讀又可寫。

六、accept()函式

1.阻塞模式

如果在乙個阻塞套介面上呼叫accept()函式,而且沒有新的連線,程序會進入睡眠狀態。

2.非阻塞模式

如果在乙個非阻塞套介面上呼叫accept()函式,而且沒有新的連線,將返回ewouldblock錯誤。

3.一種非阻塞模式例子的問題及解決辦法

問題描述:在伺服器端偵聽套介面採用阻塞的方式工作,並且使用select檢測是否有已經建立起的連線,如果有則呼叫accept()函式接收該連線,問題是如果客戶端首先呼叫connect()函式連線伺服器後立刻又呼叫close()函式關閉該連線,而在伺服器端,在select()函式返回和呼叫accept()函式之間,接收到客戶端的斷開,則會刪除該套介面在已連線套介面中的內容,所以伺服器將會阻塞在accept()函式,直到有客戶連線才返回。

解決辦法:(1).如果用select來獲知何時有連線已就緒可以accept時,總是把偵聽套介面置為非阻塞,同時(2).在後面的accept呼叫中忽略以下錯誤:ewouldblock(berkeley的實現在客戶放棄連線時出現的錯誤)、econnaborted(posix.1g的實現在客戶放棄連線時出現的錯誤)、eproto(svr4的實現在客戶放棄連線時出現的錯誤)和eintr(如果訊號**獲)。

七、select()函式

select()函式準備好讀的條件:

1>.套介面有資料可讀

2>.該連線的讀這一半關閉(也就是接收了fin的tcp連線)。對這樣的套介面進行讀操作將不阻塞並返回0(也就是返回eof)。

3>.該套介面是乙個偵聽套介面且已完成的連線數不為0。

4>.其上有乙個套介面錯誤待處理,對這樣的套介面的讀操作將不阻塞並返回-1,並設定errno,可以通過設定so_error選項呼叫getsockopt函式獲得。

select()函式準備好寫的條件:

1>.套介面有可用於寫的空間。

2>.該連線的寫這一半關閉,對這樣的套介面進行寫操作將產生sigpipe訊號。

3>.該套介面使用非阻塞的方式connect建立連線,並且連線已經非同步建立,或則connect已經以失敗告終。

4>.其上有乙個套介面錯誤待處理。

八、read()函式和recv函式

read()函式返回值代表的意義:

1>.如果對方tcp傳送資料,則套介面就變為可讀且read返回大於0的值(即資料的位元組數)。

2>.如果對方tcp傳送乙個fin(對方程序終止),套介面就變為可讀且read返回0(檔案結束)。

3>.如果對方tcp傳送乙個rst(對方主機崩潰並重新啟動),套介面就變成可讀且read返回-1,返回的錯誤號errno為econnreset。

九、write()函式和send函式

如果向乙個接收了fin的套接字進行寫操作是可行的,但如果向乙個接受了rst的套接字進行寫操作則是致命的,核心會向該程序傳送乙個sigpipe訊號,返回epipo,該錯誤型別預設為終止程序。

sigpipe訊號

向乙個接受了rst的套接字進行寫操作時,核心會向該程序傳送乙個sigpipe訊號,該訊號的預設行為是終止程序,因此程序必須捕獲它以免被不情願的終止。

linux socket程式設計相關知識的總結

1 socket程式設計中採用的協議族主要有兩種 1 網路協議族 形式如 af inet,pf inet等 2 本地unix域格式的協議族 形式如 af local,af unix等 注 協議族的選擇體現在 int socket int domain,inst type,int protocol 函...

linux socket 程式設計

兩段程式 可用於開發板和主機之間的資料傳輸,很管用!file client.c檔案傳輸客戶端程式示例 本檔案是客戶機的 include for sockaddr in include for socket include for socket include for printf include f...

linux socket程式設計

雙休日無聊透頂,看了四五集 反恐24小時 實在不想看了,於是就想搞linux的socket programming來玩玩,前期資料都準備好 早就想寫個看看了。首先,寫個簡單的client端的程式 呵,其實是copy!server端用的是網上當的乙個除錯工具 一開始用的是以前用過的乙個多執行緒執行的介...