網路程式設計之bind 的未解之謎

2021-09-29 04:00:32 字數 2964 閱讀 4033

相信大家還記得我們之前寫到的伺服器函,下面博主還是給出之前服務前端的函式呼叫順序。

伺服器端:

socket()

-->

bind()

-->

listen()

-->

accept()

-->

read()

/write()

--->

close()

socket()

//建立套接字

bind()

//分配套接字位址

listen()

//等待連線請求狀態

accept()

//允許連線

read()

/write()

//進行資料交換

close()

//斷開連線

首先我們給出bind()函式各個引數的含義。

#include

#include

intbind

(int sockfd,

const

struct sockaddr *addr, socklen_t addrlen)

;引數的含義

第乙個引數 int sockfd:

socket檔案描述符

第二個引數 const

struct addr:

構造出ip位址加埠號

第三個引數 socklen_t addrlen:

sizeof

(addr)長度

返回值:

成功返回0,失敗返回-

1, 設定errno

伺服器程式所監聽的網路位址和埠號通常是固定不變的,客戶端程式得知伺服器程式的位址和埠號後就可以向伺服器發起連線,因此伺服器需要呼叫bind繫結乙個固定的網路位址和埠號

第乙個引數相信大家應該已經不陌生了。sockfd 就是在呼叫 socket()之後返回的socket檔案描述符,為 int型,所以在用的時候,我們需要定義乙個 int sockfd來接受。大家後面看伺服器客戶端的時候,也能明白前面的 int sockfd是什麼意思了。就是為了接受socket()函式呼叫成功後返回的sockfd描述符。

這個函式比較複雜,這是乙個傳入引數。裡面更是一層套一層。

下面是書中的(以後用的都是 struct sockaddr_in)至於為什麼,這就牽扯到歷史原因了,大家記住就好。

如果有小夥伴想要知道到底是什麼歷史原因博主也就在這裡給大家分享一下:

如果有小夥伴想要知道到底是什麼歷史原因博主也就在這裡給大家分享一下:

strcut sockaddr 很多網路程式設計函式誕生早於ipv4協議,那時候都使用的是sockaddr結構體,為了向前相容,現在sockaddr退化成了(void *)的作用,傳遞乙個位址給函式,至於這個函式是sockaddr_in還是sockaddr_in6,由位址族確定,然後函式內部再強制型別轉化為所需的位址型別。

後續如 sockadd_in對以前的結構體的14位元組進行了詳細劃分,但是卻改變了結構體的名字,如果直接將這樣的引數傳給linux,linux是不認的,所以我們就需要改變他的型別。

目前涉及到要牆磚引數的三個函式:

第二個引數裡面包含了 ip和埠號,以及你在使用socket()裡面的第乙個引數

也就意味著你的結構體裡面的有乙個引數和socket()裡面的第乙個引數是一致的。

那個引數就是

剩下的兩個引數就是 sin_port----->埠號 最後乙個就是ip位址了。也就是它導致了結構體內部巢狀了乙個結構體。具體原因就是網路中使用的是網路位元組序,而我們常用的是點分十進位制的ip表示,也就是下面的這種

就是為了描述第二個引數的大小而設計的 socklen其實就是利用typedef 的int型
大家在使用bind()函式之前 一般要的步驟是:

1.清空網路位址

2.把ip和埠號以及對應的協議繫結到結構體裡面,然後再把結構體傳入到bind()的第二個引數裡面。

也就是一下**

struct sockaddr_in servaddr;

//為了讓bind()繫結ip和埠號而定義的

bzero

(&serv_addr,

sizeof

(serv_addr));

//將網路位址清空

memset

(&serv_addr,0,

sizeof

(serv_addr));

//z這個方法也可以

servaddr.sin_family = af_inet;

//與socket()的第乙個引數 int domain一樣的協議

servaddr.sin_addr.s_addr =

htonl

(inaddr_any)

;//繫結ip

servaddr.sin_port =

htons

(6666);

//繫結埠號

bind

(serv_addr,

(struct sockaddr*

)&serv_addr,

sizeof

(serv_addr));

好了就跟新這麼多吧,一般也就是這麼寫的了,最多在家判斷條件而已,宿舍斷電了,最後的都是博主抹黑打出來的,真的不容易啊、

後面的 htons這些 inaddr_any後續會講到的。

執行緒的未解之謎

這是檢驗多執行緒可見性 volatile關鍵字 的時候發現的問題。請不要再迴圈中使用system.out.println 這種 因為他是被synchronized修飾的,所以沒法用來檢測。有沒有大神能解釋一下,下面這些案例是什麼鬼?請不要說加volatile synchronized能解決這種情況,...

大腦的9大未解之謎

大腦的9大未解之謎 1.大腦為什麼有時間的意識 為什麼人人都自帶 生物鬧鐘 比如想要第二天早晨辦的很緊急的事,清晨一起床就想起來了 當然,健忘者另當別論 等待的時間越長,你會感到越急躁。換句話說,你是有意識的。這個複雜的話題從一開始就困擾著科學界,對於意識,只有哲學家給出個乙個詳細的定義,但意識到底...

網路程式設計之listen與bind

今天根據 unix 網路程式設計 卷1 第四章的4.4和4.5的習題要求 嘗試把服務端的listen和bind分別去掉,看看會發生什麼 首先把listen去掉,然後我發現我竟然這麼做了,開始真是嚇死,螢幕一直滾,不斷地刷屏啊,因為我讓服務端列印來自客戶端的套接字 ip位址和埠資訊,一直刷的是 cli...