bind


使用格式

#include <sys/types.h>

#include <sys/socket.h>

int bind(int sockfdconst struct sockaddr *addr,socklen_t *addrlen);

功能描述

當用socket()函數創建套接字以後,套接字在名稱空間(網絡地址族)中存在,但沒有任何地址給它賦值。

參數

 參數
sockfd 
指定地址與哪個套接字綁定,這是一個由之前的socket函數調用返回的套接字。調用bind的函數之後,該套接字與一個相應的地址關聯,發送到這個地址的數據可以通過這個套接字來讀取與使用。
 
參數
addr 
指定地址。這是一個地址結構,並且是一個已經經過填寫的有效的地址結構。調用bind之後這個地址與參數sockfd指定的套接字關聯,從而實現上面所說的效果。
 
參數
addrlen 
正如大多數socket接口一樣,內核不關心地址結構,當它複製或傳遞地址給驅動的時候,它依據這個值來確定需要複製多少數據。這已經成爲socket接口中最常見的參數之一了。

 

bind()把用addr指定的地址賦值給用文件描述符代表的套接字sockfdaddrlen指定了以addr所指向的地址結構體的字節長度。一般來說,該操作稱爲“給套接字命名”。

通常,在一個SOCK_STREAM套接字接收連接之前,必須通過bind()函數用本地地址爲套接字命名。

 

備註:

調用bind()函數之後,爲socket()函數創建的套接字關聯一個相應地址,發送到這個地址的數據可以通過該套接字讀取與使用。

bind()函數並不是總是需要調用的,只有用戶進程想與一個具體的地址或端口相關聯的時候才需要調用這個函數。如果用戶進程沒有這個需要,那麼程序可以依賴內核的自動的選址機制來完成自動地址選擇,而不需要調用bind()函數,同時也避免不必要的複雜度。在一般情況下,對於服務器進程問題需要調用bind()函數,對於客戶進程則不需要調用bind()函數。

套接字的命名規則在不同的網絡協議族中有所不同。對於AF_INET參看ip(),對於AF_INET6參看ipv6(),對於AF_INET6參看unix(),對於AF_APPLETALK參看ddp(),對於AF_APPLETALK參看packet(),對於AF_X25參看x25(),對於AF_NETLINK參看netlink()。

傳送給參數addr的實際結構依賴於網絡協議族。sockaddr結構定義爲如下格式:

  1. struct sockaddr {  
  2.     sa_family_t     sa_family;  
  3.     char            sa_data[14];  
  4. }  

該結構的唯一目的是強制結構指針在addr參數中傳送,以避免編譯過程出現warning。參看如下實例。

返回值

成功,返回0;出錯,返回-1,相應地設定全局變量errno。

錯誤

EACCESS

地址空間受保護,用戶不具有超級用戶的權限。

EADDRINUSE

給定的地址正被使用。


原文:http://blog.csdn.net/david_xtd/article/details/7090590

在最開始接觸bind的時候,只是在寫基於tcp的server端的時候,知道在listen之前需要先bind一下,用來確保socket能在某個固定的端口監聽。而bind的時候,函數參數中的端口填自己將要綁定的端口就行;而IP地址,需要填本機的IP,但是也可以用一個宏INADDR_ANY代替,用這個宏就可以不用查找本機的IP,它就可以代替本機的IP。當時只覺得這個INADDR_ANY比較神奇,但是由於當時覺得用起來很方便,也沒出啥問題,也就沒有再深究


  但是最近在做RTSP服務器的時候,有種特殊的應用,導致我不得不對bind這個函數仔細地看一下。
  我們知道無論是UDP還是TCP,socket都會與一個本地的IP和端口想對應,我們往往把這個IP和端口稱之爲socket的源地址和源端口。當我們作爲客戶端利用socket去發送數據時,很少會去考慮這個源地址和源端口到底是什麼,我們更關心的是它的目的地址和端口。我們往往只有在監聽的時候,纔去考慮這個源端口,所以我們在監聽的時候會去用bind。當我們bind之後,內核就會將這個socket的源端口鎖定到我們設定的端口上。但是這就有一個問題,這個bind綁定端口,是將本來沒有源端口的socket綁定到我們指定的端口上,還是將一個已經分配了端口的socket重定向到我們指定的端口上呢?
  在《UNIX網絡編程》這本書中提到:“如果一個TCP客戶或者服務器未曾調用bind捆綁一個端口,當調用connect或listen時,內核就要爲相應的套接字選擇一個臨時接口。”從這句話中可以判斷出,其實在調用socket函數創建socket時,內核還並未給socket分配源地址和源端口。而對於UDP,我猜測在調用sendto發送數據時,在未捆綁端口的情況下,內核也會隨機分配端口。
  而我遇到的特殊應用要求我在用UDP發送數據之前要告訴對方我的發送端口,這也就意味着我在sendto之前必須要捆綁端口,因此我在發送數據之前就得調用bind函數綁定一下端口了。但是我就在想內核既然有隨機分配端口的能力,而我需要的也只是讓它綁定一下而不用綁定在固定端口的業務,socket中應該能夠提供這種業務。然後果然我發現bind就具備這種能力,當bind的參數中端口地址爲0的時候,這時候就是由內核分配端口。這樣我就不用考慮端口地址重複的問題,而放心的把這個問題交給內核處理了。
  就在發現bind的這個機制的同時,我發現其實bind對於源地址也同樣具備這種處理方式,當系統具有多IP(多網卡)的情況,當我們把bind函數中的ip參數置0時,就是由內核自己選擇分配IP。而之前一直覺得很神奇的INADDR_ANY其實一點也不神奇,它的值其實就是0所以當我們只有單一IP的時候,我們就可以用INADDR_ANY去代替那個單一的IP,因爲內核分配的時候只能選擇這一個IP。從而造成了INADDR_ANY就是本機IP的現象

 

原文:http://www.cnblogs.com/nightwatcher/archive/2011/07/03/2096717.html

發佈了13 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章