客户端的socket是否需要bind?
bind() 函數的定義與作用——
????將一本地地址與一套接口捆綁。本函數適用于未連接的數據報或流類套接口,在connect()或listen()調用前使用。
????當用socket()創建套接口后,它便存在于一個名字空間(地址族)中,但并未賦名。bind()函數通過給一個未命名套接口分配一個本地名字來為套接口建立本地捆綁(主機地址/端口號)。
服務端——????
? 服務端進程bind端口:基本是必須要做的事情,比如一個服務器啟動時(比如freebsd),它會一個一個的捆綁眾所周知的端口來提供服務,同樣,如果bind了一個端口就表示我這個服務器會在這個端口提供一些“特殊服務”。
? 服務端進程bind IP地址:目的是限制了服務端進程創建的socket只接受那些目的地為此IP地址的客戶鏈接;
? ?但是經常看見一些server端的代碼是這么寫的(沒有明確寫明bind 的IP):
| 1 | servaddr.sin_addr.s_addr = htonl(INADDR_ANY); |
| 1 | bind(Sockfd, (struct sockaddr *)servaddr, sizeof(struct servaddr)); |
這種設定是因為該server可能有多個網卡(多個IP),但不確定client會從哪個網卡連接進來。這么設置可以使bind IP這個過程推遲,直到client端與server建立連接后,server才確定bind 哪個IP.
客戶端——
?
| 1 | int connect ( SOCKET s,const struct sockaddr * name,int namelen ); |
| 1 | int sendto ( socket s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ; |
? ? UDP socket客戶端調用sendto()函數同樣也只需要填寫server端的地址信息(倒數第二個參數),系統依然是自動分配了端口給該socket。
客戶端bind了地址可能帶來的問題:
?如果在client端的程序里,bind()了某個端口(比如 3456)。首先,得考慮這個端口是否被其他的程序占用了(增加了實現的難度和麻煩)。第二,如果client端是hard code了bind這么一個端口(3456),那么在這臺電腦上,就只能運行一個客戶端,因為同一個端口只能給一個socket使用。?
總結:
? bind地址的意義在于,可以提前確定端口號——比如:用于瀏覽網頁服務的80端口,用于FTP服務的21端口等。server有這個需求,但是client基本沒這個需求。
其他:
? 使用bind函數時,通過將my_addr.sin_port置為0,函數會自動為你選擇一個未占用的端口來使用。
? Bind()函數在成功被調用時返回0;出現錯誤時返回"-1"并將errno置為相應的錯誤號。
??需要注意的是,在調用bind函數時一般不要將端口號置為小于1024的值,因為1到1024是保留端口號,你可以選擇大于1024中的任何一個沒有被占用的端口號。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的客户端的socket是否需要bind?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MPlayer开发
- 下一篇: socket的accept函数解析以及服