套接字程式設計注意事項

2021-08-15 16:36:31 字數 1843 閱讀 6623

被中斷的系統呼叫

驚群問題

read

記憶體對齊和位元組序

tcp粘包問題 訊號

sigchld訊號和殭屍程序

多程序伺服器需要處理sigchld訊號,sigchld缺省會導致程序終止;不**子程序會導致殭屍程序太多;迴圈是因為訊號不會累計,避免多個子程序同時結束,而只**乙個子程序。

- 建議做法:捕捉訊號,並迴圈呼叫waitpid直到返回值小於0。

sigpipe訊號

當乙個程序向某個已收到rst的套接字執行寫操作時,核心向該程序傳送乙個sigpipe訊號。並且,不論該程序是捕獲了該訊號還是從其訊號處理函式返回,寫操作都將返回epipe

- 可能產生rst的原因:向某個已關閉的套接字寫。

- 可能產生sigpipe的原因:向某個已關閉的套接字執行第一次寫操作,會受到rst;第二次就會產生sigpipe訊號,同時返回epipe錯誤。

被中斷的系統呼叫

慢系統呼叫包括:read、readv、write、writev、wait、waitpid、epoll_wait、epoll_ctl、connect等。這些系統呼叫在訊號處理函式返回後,會闡述eintr錯誤。雖然有些系統呼叫會重啟,但是系統實現不同最好都處理。

- 建議做法:判斷errno == eintr再重複繼續執行。

驚群問題

父程序epoll_create得到epoll_fd,fork()後子程序執行epoll_wait,當連線請求過來的時候,只有乙個子程序會accept成功,其他子程序返回eagain

解決方案:

accept前加鎖;

linux核心已經解決了;

read

如果在乙個套接字上完成乙個 read 操作並得到乙個為 0 的返回值,這表明遠端套接字端的對等層呼叫了 close api 方法。

同樣,可以用 write api 函式來探測對等套接字的閉包。在這種情況下,接收 sigpipe 訊號,或如果該訊號阻塞,write 函式將返回 -1 並設定 errno 為 epipe。

記憶體對齊和位元組序

套接字適合傳送無結構二進位制位元組流或 ascii 資料流,傳送結構化的資料時,記憶體對齊格式不相同就會造成資料無法解析。大小端的問題也一樣,不過可以都轉化為網路位元組序(網路位元組序是大端)。

問題:

tcp粘包問題

tcp一次會收到多個包,造成粘包等;

udp自帶幀同步,每次read只會返回乙個包;

處理粘包

對於粘包,需要clientserver定製報頭,說明長度字段。

伺服器端能做的:判斷位元組,每次取包頭長度的字段;多餘長度放到緩衝區;不足長度直接放到緩衝區;對於長度異常的字段做處理;前面乙個流的錯誤會影響後面的,所以對於每乙個使用者,定義乙個緩衝區;報文完整才放到交付處理。如果異常直接斷開連線,清理緩衝區。

實現效果如下圖:

recv 22 22

recv 18 88

recv 22 70

recv 18 48

recv 30 30

UNIX域套接字 填充時注意事項

unix域協議用於單個主機中伺服器和客戶端通訊 屬於ipc 提供位元組流套接字 類似tcp 和資料報套接字 類似udp struct sockaddr un 存放在sun path陣列中的路徑名稱必須以空字元結尾。如果沒有指定位址,那麼就是sun path 0 的值,為0,因為使用前我們 對結構體清...

程式設計注意事項

1.動態輸出表頭或資料 每次輸出之前,請先清空表頭以及資料再新增。2.一般資料都要分頁,請直接加上分頁 3.重複性資料的校驗 介面接收資料 1.介面接收資料,一般型別接受 例如 string 列印日誌,之後再轉換成自己想要的格式json等。需求評審 問題一 大面問題 1.是什麼?2.怎樣玩?業務流程...

VBA程式設計 注意事項

1 在自定義函式前加上 private 關鍵字進行宣告,該函式將不會出現在 excel的 貼上函式 對話方塊中,但仍然可以在公式中運用它們。如果是專門為其他的 vba過程開發的自定義函式,則應該使用 private 關鍵字進行宣告。2 通常,使用者自定義函式後,在 貼上函式 對話方塊中將會出現在 使...