目錄
端口號
網絡字節序
socket編程
接口
sockaddr結構
udp網絡程序
創建套接字
綁定
接收
發送
客戶端需要綁定嗎?
客戶端執行方法
本地環回地址
終端文件
代碼
tcp網絡程序
SOCK_STREAM
監聽
查詢網絡信息
獲取新連接
地址轉換函數
客戶端綁定
多進程版本
關閉多余文件描述符
如何解決父進程等待子進程會阻塞的問題?
多線程版本
線程池版本
守護進程
進程與任務的關系
端口號
網絡通信不僅包括建立連接,還有應用層的通信。
端口號負責判斷發給上層哪一個應用。
發送方和接收方在報頭中有對應的源端口號和目的端口號。
這種基于ip+端口的通信方式叫socket。
端口號與進程id
綁定的過程就是把進程pcb和哈希表中端口對應位置關聯起來。
網絡字節序
轉換接口
socket編程
接口
sockaddr結構
套接字有三種
設計者不想寫三套接口,就需要把類型統一,所以都傳入sockaddr結構體,判斷地址類型從而決定套接字的種類。
udp網絡程序
創建套接字
第一個參數是域的類型
第二個參數是套接字類型
第三個參數是協議類型
返回值是文件描述符
綁定
第二個參數是自己構造一個結構體傳進去
family表示域類型,port是端口號,addr是ip
本主機的端口號要發送出去會經過網絡,所以要轉網絡字節序。
ip要發出去也要轉網絡字節序。
整數ip和字符串ip快速轉換
整數轉字符串:構造四個八位整型的結構體,將整數強轉該結構體類型,分別訪問結構體并轉字符串。
字符串轉整型:將整數強轉四個八位結構體類型,分別訪問并賦值。
第三個參數是結構體大小。
?綁定不推薦直接綁定具體ip一般寫0.0.0.0,因為有一些主機有多個網卡,綁定一個其他網卡就接收不了了。
INADDR_ANY表示接收任意地址
綁定端口盡量大一點,1023以下是內置端口。
接收
從套接字中讀一個報文
結構體是輸出型參數,負責獲得對方的信息。
buffer是對方發送的內容,結構體是對方的信息
發送
結構體是發送目標的信息
客戶端需要綁定嗎?
客戶端執行方法
把代碼進行分層,處理方法分開。
popen把字符串當成命令,創建子進程,父子進程建立管道,子進程執行命令,結果返回給父進程。
本地環回地址
往下貫穿協議棧,然后又往上返回,不進入網絡
終端文件
把輸入到2號文件的內容重定向到2號終端。
xshell可以開很多個終端,查詢終端。
代碼
?socket_lesson/my_udp · lyh/linux - 碼云 - 開源中國
tcp網絡程序
SOCK_STREAM
選擇SOCK_STREAM面向字節流。
監聽
查詢網絡信息
l表示listen,p表示對應進程,t表示tcp。
獲取新連接
返回值也是文件描述符
accept返回的文件描述符負責真正的IO服務,參數的文件描述符負責建立連接,一般叫作監聽套接字。
連接獲取失敗就繼續重新獲取。
地址轉換函數
客戶端綁定
多進程版本
關閉多余文件描述符
多進程版,子進程會繼承文件描述符信息,讓子進程負責IO就可以把監聽套接字關了,父進程不關注IO也可以把不需要的文件描述符關了。
如何解決父進程等待子進程會阻塞的問題?
利用孫子進程解決,把事情給孫子進程做,子進程直接退出,父進程也等待完畢。
第二種方法:用信號忽略
多線程版本
detach線程分離從而不用等待子線程?
當靜態函數想訪問類內成員時,可以把線程的參數結構加一個該類的指針。
線程池版本
假如服務端正在寫,客戶端關閉了文件,讀端關閉了,寫端也會被迫關閉。
這樣可以防止寫端被關閉。防止服務端被關閉就對這個信號忽略。
客戶端重連
服務器掛掉無法立即重新啟動,解決方法:
守護進程
每一個用戶登陸都會產生一個會話,會話里面會生成bash進程提供命令行服務,一個會話可以有一個前臺進程多個后臺進程,鍵盤和信號只能影響前臺進程。
&變成后臺任務,jobs查看后臺任務,fg把后臺變成前臺
fg變成前臺后如何變回后臺:先用信號暫停,然后用bg。信號暫停后任務會以停止狀態回到后臺,bash自動回前臺。
進程與任務的關系
任務是一個具體事情,它可以被一個進程完成,也可以被一個進程組完成。
守護進程可以不受用戶退出,注銷(關閉會話)的影響。
做法:把目標進程(組)遷移到一個新的會話。
調用接口的進程不能是該進程組的組長。解決方法:讓子進程調用。
第二種方法: