無連接的socket的客戶端和服務端以及面向連接的socket的服務端通過調用bind函數來配置本地信息。使用bind函數時,通過將my_addr.sin_port置為0,函數會自動為你選擇一個未占用的端口來使用。
Bind()函數在成功被調用時返回0;出現錯誤時返回"-1"並將errno置為相應的錯誤號。需要注意的是,在調用bind函數時一般不要將端口號置為小於1024的值,因為1到1024是保留端口號,你可以選擇大於1024中的任何一個沒有被占用的端口號。
有連接的socket客戶端通過調用Connect函數在socket數據結構中保存本地和遠端信息,無須調用bind(),因為這種情況下只需知道目的機器的IP地址,而客戶通過哪個端口與服務器建立連接並不需要關心,socket執行體為你的程序自動選擇一個未被占用的端口,並通知你的程序數據什么時候打開端口。(當然也有特殊情況,linux系統中rlogin命令應當調用bind函數綁定一個未用的保留端口號,還有當客戶端需要用指定的網絡設備接口和端口號進行通信等等)
總之:
1.需要在建立連接前就知道端口的話,需要 bind
2.需要通過指定的端口來通訊的話,需要 bind
1.需要在建立連接前就知道端口的話,需要 bind
2.需要通過指定的端口來通訊的話,需要 bind
具體到上面那兩個程序,本來用的是TCP,客戶端就不用綁定端口了,綁定之后只能運行一個client的程序屬於自己人為設定的障礙,而從服務器那邊得到的客戶機連接端口號(是系統自動分配的)與這邊客戶機綁定的端口號根本是不相關的,所以客戶端綁定也就失去了意義。
首先,服務器和客戶端都可以bind,bind並不是服務器的專利。
客戶端進程bind端口:由進程選擇一個端口去連服務器,(如果默認情況下,調用bind函數時,內核指定的端口是同一個,那么調用多個調用了bind()的client程序,會出現端口被占用的錯誤)注意這里的端口是客戶端的端口。如果不分配就表示交給內核去選擇一個可用端口。
客戶端進程bind IP地址:相當於為發送出去的IP數據報分配了源IP地址,但交給進程分配IP地址的時候(就是這樣寫明了bind IP地址的時候)這個IP地址必須是主機的一個接口,不能分配一個不存在的IP。如果不分配就表示由內核根據所用的輸出接口來選擇源IP地址。
一般情況下客戶端是不用調用bind函數的,一切都交給內核搞定,YES!
服務端進程bind端口:基本是必須要做的事情,比如一個服務器啟動時(比如freebsd),它會一個一個的捆綁眾所周知的端口來提供服務,同樣,
如果bind了一個端口就表示我這個服務器會在這個端口提供一些“特殊服務”
。
服務端進程bind IP地址:目的是限制了服務端進程創建的socket只接受那些目的地為此IP地址的客戶鏈接,一般一個服務器程序里都有
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 只是針對IP4,IP6代碼不太一樣
這樣一句話,意思就是:我不指定客戶端的IP,隨便連,來者不拒!
總之只要你bind時候沒有指定哪一項(置為0),內核會幫你選擇。
注意:只能對一個socket描述符綁定一次,不能綁定多次,除非前面已經將該描述符close了。反過來一個端口也只能被綁定到同一個socket描述符上,除非他們使用的不同的協議。