unix網路程式設計

2022-04-06 14:01:43 字數 3319 閱讀 1335

任何tcp的實現都需要為msl選擇乙個合適的值, rfc的建議值是2分鐘。分組可能出現迷途,若迷途分組在msl中找到路, 造成重複,tcp必須修復

time_wait存在的理由:

可靠的實現全雙工的連線和終止

考慮最終ack丟失的情況,

允許老的重複分組在網路中消逝

tcp的化生身現象, 因為time_wait的時間是2msl, 故time_wait可以確保先前化身(incarnation)的老重複分組都已經在網路中消失了

不過存在乙個例外: 如果到達的syn的序列號大於前一化身的結束序列號,源自berkely的實現應該給當前time_wait狀態的連線啟動新的化身

連線: 類似tcp, 但是是四路握手, 主要差別在於作為sctp整體的一部分的cookie的生成

終止: 不允許"半關閉"

連線和終止

考慮如下**

void detail() 

close(connfd); //注意這裡}}

我們知道, tcp套介面字呼叫close會導致傳送乙個fin, 然後會連線終止, 為什麼這裡不會呢?事實上, 每個檔案或socket都會有乙個引用計數(引用計數在檔案表項中維護), fork的時候會讓計數*2, 而close讓計數-1, 所以不會出現問題, 真正socket的清理和資源的釋放過程要等計數為0的時候才會發生

注意, 如果一直fork了也不close, 那麼會耗盡所有可用的檔案描述符, 導致連線一直開啟著

如果我們確實想要某個tcp連線上傳送乙個fin, 那麼我們可以改用shutdown函式.

accept, 是乙個慢系統呼叫, 多數網路支援函式都屬於這個型別. 當阻塞於慢系統呼叫的乙個程序捕獲某個訊號且進入相應的處理函式的時候, 該系統呼叫可能返回乙個eintr錯誤.(有的核心自動重啟某些被中斷的系統呼叫),不過為了便於移植, 我們必須對eintr有所準備, 乙個處理辦法就是

while(true) 

}

注意: 有乙個函式我們不能這樣處理, 就是connect, 如果他出了eintr, 再次呼叫會立即返回乙個錯誤, 我們必須用select函式來等待連線完成

如下圖的情況的時候,

如何處理這種問題依賴於不同的實現, 之後再說所有客戶端和伺服器都從呼叫socket開始, 客戶端connect, 服務端bind, listen和accept, 大多數tcp都是併發的, 而大多數udp卻是迭代的

io復用並非只侷限於網路程式設計, 許多重要的應用也要採用這個技術

在了解io復用之前需要先回顧unix的5種io模型: 阻塞式, 非阻塞式, 復用, 訊號驅動io, 非同步io

其中5種模型的比較

5種模型的比較

該函式select乙個'核心等待'發生, 並且只有在乙個或多個事件發生(或經歷了一段時間後)才喚醒它

舉個例子, 比如我們可以通過呼叫select函式使得核心僅在以下情況返回:

pselect函式

posix發明的, 有許多的unix變種支援他

poll和select類似, 只不過在處理流函式的時候能夠提供額外的資訊, 先不扯太多理論, 直接看**還好懂

#include "unp.h"

#include #define open_max 10

int main()

if (i == open_max)

err_quit("too many clients");

if (i > maxi)

maxi = i;

if (--nready <= 0)

continue;

}//別的都是client socket

for (i = 1; i <= maxi; ++i)

else

perror("read error");

}else if (n == 0)

else

write(sockfd, buf, n);

if (--nready <= 0)

break;}}

}}

有很多方式來設定和影響套接字選項, 例如getsockopt,setsockopt,fcntl,ioctl關於傳輸層的套接字選項, 請自行google或參考有關文件和書籍

udp程式設計模型

建立socket的時候要把sock_stream改成sock_dgram

類似與標準的read和write, 不過需要3個額外的引數: flags, from, addrlen, flags引數先不說, 暫時把他當成0, 後續會解釋; from和addrlen引數和accept的最後兩個引數類似

recvfromsendto都可以用於tcp, 儘管通常沒有理由那麼做

void

dg_echo(int sockfd, sa* pcliaddr, socklen_t clilen)

}int

main()

**雖簡單, 但是有幾個細節需要注意

更多的udp細節不在此贅述

留坑.. 以後補上.....

ipv4和ipv6的互操作性

UNIX網路程式設計

在unix network programming 的 3.7 inet pton and inet ntop functions 中提到中有如下兩個巨集定義 define inet addrstrlen 16 for ipv4 dotted decimal define inet6 addrstr...

unix 網路程式設計 UDP

udp user datagram protocol 程式傳送資料給 udp socket,資料先被封裝成 udp資料報,然後又被封裝成ip資料報,然後被傳送到目標方。資料是否被正確傳輸無任何保證 是否到達目標方,是否按正確順序到達,是否目標方只收到乙份資料 每個udp資料報都有長度,這個長度包含在...

Unix網路程式設計思想

本次部落格主要總結參考 unix網路程式設計 卷一前四章的知識,對tcp一對一通訊進行重新改造和分析,經典就是經典,無可替代!一 為什麼使用包裹函式listenfd socket af inet,sock stream,0 包裹函式socket定義為 int socket int family,in...