網路程式設計雜項 (持續更新)

2021-05-25 05:12:29 字數 1759 閱讀 2393

by [email protected]

——記錄一些小問題,陷阱

1. 呼叫bind時,如果位址是0(就是inaddr_any那個巨集),就繫結本地所有ip,如果埠是0,就隨機選擇乙個可用的埠(想要知道具體埠,可以呼叫getsockname檢視)

2. send recv 與 read write 的區別主要在於:send 和 recv 可以設定一些 flag,而 read 和 write 則沒有

3. 阻塞與非阻塞:呼叫 api 時是否需要等待完成時才返回

4. send/sendto 的一般返回情況:

非阻塞或超時——根據當前緩衝區空閒長度,盡力向套接字緩衝區拷貝,完成了多少算多少,立返回

阻塞——完成所有資料的拷貝,才返回。如果現在空閒區大小不夠,會等待至空閒區夠了並拷貝,完成拷貝後返回

tcp 是資料流,所以 send 的資料可以很大,而不會返回訊息過長的錯誤;

udp 因為僅組裝成乙個資料報,不能夠分開多次傳送,所以如果傳送的資料量大於緩衝區長度,會立即返回訊息過長的錯誤。

非阻塞的傳送可以是套接字級別的,通過 setsockopt 設定;也可以是訊息級別的,通過 send 呼叫時的 msg_dontwait 標記

-- 可以用非同步方式,將套接字設定為非阻塞,但是需要注意檢查 send 函式的返回值,驗證 recv 收到的包的完整性

5. udp 下也可以使用 connect,同 tcp 相比,並沒有握手過程,只是設定了套接字資料結構裡面的遠端位址部分

6. 在 tcp 套接字被 shutdown 後,呼叫讀寫該套接字的 api 除了返回 epipe 錯誤外,還會產生 sigpipe 訊號(預設操作是退出程序)。可以在呼叫 api 時,通過 msg_nosignal 標記來告知核心,無需發出這一訊號。

7. udp 收包時,如果緩衝區大小比包長要小,那其行為是未定義的,建議最好一次收個夠

8. tcp 發包時,擔心因為包太小無法即時傳送出去的話,可以設定 tcp_nodelay 套接字選項

9. udp 發包過快會造成本地或遠端被「淹沒」。考慮乙個 udp 伺服器,如果接收緩衝區滿了,此時還有 udp 資料到達,則協議棧會丟棄新到達的資料。(僅從機器負載去看,難以斷定是否會「淹沒」,只能估算;淹沒發生時,程序通常忙於幹其他事情或被阻塞,因此從可控的角度來講,只好盡量降低 cpu 負載、盡量採用非同步)

udp 丟包的幾種情況:網路導致,緩衝區長度不夠長導致(rmem_max、sol_sndbuf),緩衝區已滿

10. tcp connect 時,預設超時因系統不同而不同,一般都要那麼幾分鐘,如果想要主動控制這個超時,有幾種方法:修改核心引數、使用非同步的 select 和 epoll 檢視是否返回套接字可寫,如果是 linux 環境,那麼 sol_sndtimeo 選項也能起作用。

11. linux下多個子程序可以競爭accept同乙個套接字,程序/執行緒池基本就是這樣一種思路,先fork幾個再讓它們都競爭accept。監視客戶端的數量,可以動態地增加、減少程序數。

12. 非同步connect時,如果超時會返回乙個出錯事件,錯誤碼被置為einprogress

13. 編寫乙個完善的伺服器,要考慮:常見訊號是否已經捕獲並處理(如sigsegv、sigchld、sigpipe、sigterm、sigint等),系統api的返回值是否進行了合理的檢查,日誌體系是否完善。如果使用了epoll,還要對錯誤類事件統一處理。

14. 對tcp的情況,如果使用keepalive選項,協議棧會探測鏈結的對端是否有響應,如果沒有的話會返回套接字可讀,receive返回錯誤。

Linux網路程式設計雜項

requests not to send sigpipe on errors on stream oriented sockets when the other end breaks the connection.the epipe error is still returned.當連線斷開,如果a...

網路程式設計雜項高階

tcp聊天,server端實現 import socket sk socket.socket 例項化socket物件 address 0.0.0.0 8000 設定埠 sk.bind address 繫結ip位址和埠 sk.listen 5 監聽 while true conn,addr sk.ac...

網路流(持續更新)

最後一種最快,前兩種彼此彼此 紫書模板 include include include include include include include include include include include includeusing namespace std struct edge int...