網(wǎng)絡(luò)學(xué)習(xí)七

概述

本章主要實(shí)現(xiàn)的程序模型:


2 TCP回射服務(wù)器程序

服務(wù)器與客戶程序約定一個(gè)固定的端口,要比5000大,比49152小。
fork后子進(jìn)程第一件事就是關(guān)掉listenfd,父進(jìn)程的第一件事是關(guān)掉connfd。
在等待客戶的read調(diào)用返回出錯(cuò)后,如果是因?yàn)楸恍盘?hào)打斷,要重新調(diào)用read。

正常情況

正常啟動(dòng)
監(jiān)聽套接字處于LISTEN狀態(tài)。
客戶的connect在三路握手的第二個(gè)分節(jié)就返回了,而服務(wù)器要直到第三個(gè)分節(jié)才返回,即客戶的connect返回時(shí)服務(wù)器還沒有accept。
服務(wù)器的連接套接字處于ESTABBLISHED狀態(tài)。
正常終止
客戶端主動(dòng)關(guān)閉時(shí),客戶TCP發(fā)送一個(gè)FIN給服務(wù)器,服務(wù)器TCP響應(yīng)ACK,此時(shí)服務(wù)器處于CLOSE_WAIT狀態(tài),客戶處于FIN_WAIT_2狀態(tài)。
服務(wù)器關(guān)閉時(shí),服務(wù)器發(fā)送FIN給客戶,客戶發(fā)送ACK給服務(wù)器,連接完全終止,客戶進(jìn)入TIME_WAIT狀態(tài)。
服務(wù)器子進(jìn)程終止時(shí)給父進(jìn)程發(fā)送一個(gè)SIGCHLD信號(hào)。默認(rèn)行為是忽略,但我們必須捕捉此信號(hào),清理僵死進(jìn)程。

POSIX信號(hào)處理

信號(hào)是某個(gè)進(jìn)程發(fā)生了某個(gè)事件的通知,有時(shí)也稱為軟件中斷,通常是異步發(fā)生的,也就是說進(jìn)程預(yù)先不知道信號(hào)的準(zhǔn)確發(fā)生時(shí)刻。
信號(hào)可以:
由一個(gè)進(jìn)程發(fā)給另一個(gè)進(jìn)程
由內(nèi)核發(fā)給某個(gè)進(jìn)程
每個(gè)信號(hào)都有一個(gè)與之關(guān)聯(lián)的處置也稱行為。

處理SIGCHLD信號(hào)

多進(jìn)程下父進(jìn)程必須捕捉SIGCHLD信號(hào)以回收終止?fàn)顟B(tài)的子進(jìn)程資源,否則進(jìn)程處于僵尸狀態(tài)??梢栽谛盘?hào)處理函數(shù)中用wait或waitpid。慢速系統(tǒng)調(diào)用會(huì)被信號(hào)處理函數(shù)打斷,可能會(huì)返回EINTR錯(cuò)誤,也可能會(huì)自動(dòng)重啟。我們編寫捕獲信號(hào)的程序時(shí),必須對此有所準(zhǔn)備。例如,對accept的處理,connect被打斷后就不能被使用了。

wait和waitpid函數(shù)

通過wait和waitpid都可以獲得終止的子進(jìn)程的pid和狀態(tài),waitpid還能指定想等待的pid,options參數(shù)允許指定附加選項(xiàng),最常用的是WNOHANG,在沒有終止子進(jìn)程時(shí)不阻塞。
信號(hào)阻塞期間如果該信號(hào)產(chǎn)生了多次,解除阻塞后只能接收到一次,因此要用waitpid(-1,*,WNOHANG)來循環(huán)回收所有結(jié)束的子進(jìn)程。

accept返回前連接中止

三路握手完成,連接建立后,客戶TCP發(fā)送了RST,服務(wù)器端在調(diào)用accept前收到了這個(gè)RST。
如何處理這種中止依賴于不同的實(shí)現(xiàn)。BSD的實(shí)現(xiàn)是在內(nèi)核中處理,服務(wù)器的accept繼續(xù)阻塞,SVR4的實(shí)現(xiàn)是返回一個(gè)錯(cuò)誤給進(jìn)程。如果返回了一個(gè)錯(cuò)誤,再次調(diào)用accept就行。

服務(wù)器進(jìn)程終止

客戶與服務(wù)器連接成功后,服務(wù)器進(jìn)程如果終止(被動(dòng)),套接字被關(guān)閉,向客戶發(fā)送FIN,客戶響應(yīng)ACK,此時(shí)客戶進(jìn)程可能阻塞在用戶輸出上,看不到這個(gè)RST,此時(shí)如果進(jìn)行write,再read,就會(huì)收到預(yù)期外的EOF。

SIGPIPE信號(hào)

寫一個(gè)已收到FIN的套接字會(huì)收到RST,寫一個(gè)已收到RST的套接字會(huì)產(chǎn)生SIGPIPE信號(hào)。
如果沒有特殊的事情要做,就將SIGPIPE設(shè)置為SIG_IGN,忽略它,并在后面的讀寫操作中檢查返回的錯(cuò)誤。如果需要采取特殊措施(如寫入日志),就要捕捉該信號(hào)。但如果用了多個(gè)套接字,信號(hào)處理程序無法分辨是哪個(gè)套接字出的錯(cuò)。如果需要知道出錯(cuò)的位置,要么不理會(huì)該信號(hào),要么從信號(hào)處理函數(shù)返回后再處理write的EPIPE。

服務(wù)器主機(jī)崩潰 服務(wù)器主機(jī)關(guān)機(jī)

服務(wù)器主機(jī)崩潰時(shí),已有的網(wǎng)絡(luò)連接上不發(fā)出任何東西(如FIN)??蛻魧Ψ?wù)器的寫操作會(huì)持續(xù)重傳數(shù)據(jù),試圖接收一個(gè)ACK,直到超時(shí)。客戶隨后的readline調(diào)用會(huì)返回一個(gè)錯(cuò)誤。
可以對readline設(shè)置一個(gè)超時(shí)。如果不主動(dòng)向服務(wù)器發(fā)送數(shù)據(jù)也想檢測出服務(wù)器主機(jī)的崩潰,需要SO_KEEPALIVE套接字選項(xiàng)。

服務(wù)器主機(jī)崩潰后重啟

服務(wù)器主機(jī)在崩潰后客戶發(fā)數(shù)據(jù)前重啟完成,客戶不知道服務(wù)器主機(jī)的崩潰,發(fā)送數(shù)據(jù),但服務(wù)器TCP丟失了之前的連接信息,因此響應(yīng)RST,客戶TCP收到RST時(shí),客戶進(jìn)程正阻塞于readline調(diào)用,該調(diào)用返回一個(gè)錯(cuò)誤。

數(shù)據(jù)格式

例子:在客戶與服務(wù)器之間傳遞文本串
用sscanf獲取文本中的指定數(shù)據(jù),再用snprintf把結(jié)果轉(zhuǎn)換為文本串。
例子:在客戶與服務(wù)器之間傳遞二進(jìn)制結(jié)構(gòu)
當(dāng)這樣的客戶和服務(wù)器程序運(yùn)行在字節(jié)序不一樣的或某些類型長度不一致的兩個(gè)主機(jī)上時(shí),工作將失常。
不同的實(shí)現(xiàn)在存儲(chǔ)二進(jìn)制數(shù)據(jù)的格式上(大端小端)、相同類型的長度上、給結(jié)構(gòu)打包的方式(對齊)上都可能不同,因此直接傳送二進(jìn)制結(jié)構(gòu)絕不明智。
解決方法:

  1. 所有的數(shù)值數(shù)據(jù)作為文本串來傳遞。
    
  2. 顯式定義所支持?jǐn)?shù)據(jù)類型的進(jìn)進(jìn)制格式,并以這樣的格式在客戶與服務(wù)器間傳遞所有數(shù)據(jù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)、netstat -nat 查看TCP各個(gè)狀態(tài)的數(shù)量2)、lso...
    北辰青閱讀 9,700評論 0 11
  • 最近在看《UNIX網(wǎng)絡(luò)編程 卷1》和《FREEBSD操作系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)》這兩本書,我重點(diǎn)關(guān)注了TCP協(xié)議相關(guān)的內(nèi)容...
    腩啵兔子閱讀 1,278評論 0 7
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 《UNIX 網(wǎng)絡(luò)編程卷一:套接字聯(lián)網(wǎng)API》筆記 套接字 套接字編程接口,是在 TCP/IP 協(xié)議族中,應(yīng)用層進(jìn)入...
    超net閱讀 5,981評論 2 13
  • 18.1 引言 TCP是一個(gè)面向連接的協(xié)議。無論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。本章將...
    張芳濤閱讀 3,520評論 0 13

友情鏈接更多精彩內(nèi)容