TCP Socket一些東西

小 樓 一 夜 聽 春 雨發表於2016-05-13

1. 若connect失敗該套接字不可再用,必須close當前套接字,重新呼叫socket。

手冊上註明連線失敗後, socket的狀態是未知的, 所以再次connect, 可能成功, 也可能失敗.

APPLICATION USAGE
       If  connect()  fails,  the  state of the socket is unspecified.  Conforming applications should close the
       file descriptor and create a new socket before attempting to reconnect.

 

要是服務端只listen而沒有呼叫 accept 程式碼,再執行,客戶端列印:連線成功。這是因為呼叫 listen 方法後,核心為任何一個給定的監聽套接字維護兩個佇列:未完成連線佇列和已完成連線佇列。當客戶SYN到達時,如果佇列是滿的,TCP就忽略該分節,但不會傳送RST;當程式呼叫accept 時,已完成佇列的對頭項將返回給程式,如果佇列是空,則阻塞(套接字預設阻塞);

也就是說只要我呼叫了listen方法後,服務端就開啟了三次握手的開關,能夠處理來自客戶端的SYN分節了,只要三次握手完成,客戶端就會connect成功,而跟服務端呼叫accept沒任何關係,accept只是去取已完成連線佇列的對頭項。

 

2. 當bind的引數中埠地址為0的時候,這時候就是由核心分配埠。這樣我就不用考慮埠地址重複的問題,而放心的把這個問題交給核心處理了。

 

3. bind對於源地址也同樣具備這種處理方式,當系統具有多IP(多網路卡)的情況,當我們把bind函式中的ip引數置0時,就是由核心自己選擇分配IP。而之前一直覺得很神奇的INADDR_ANY其實一點也不神奇,它的值其實就是0。所以當我們只有單一IP的時候,我們就可以用INADDR_ANY去代替那個單一的IP,因為核心分配的時候只能選擇這一個IP。從而造成了INADDR_ANY就是本機IP的現象。

 

4. 如果你在bind時,使用了INADDR_ANY那麼,你將可以在所有有效的地址上進行監聽,但是Socket有一個特性:可在同一埠上繫結多個Socket。

 

5. INADDR_ANY 的具體含義是,繫結到0.0.0.0。此時,對所有的地址都將是有效的,如果系統考慮冗餘,採用多個網路卡的話,那麼使用此種bind,將在所有網路卡上進行繫結。在這種情況下,你可以收到傳送到所有有效地址上資料包。

inux下的socket INADDR_ANY表示的是一個伺服器上所有的網路卡(伺服器可能不止一個網路卡)

多個本地ip地址都進行繫結埠號,進行偵聽。

INADDR_ANY是ANY,是繫結地址0.0.0.0上的監聽, 能收到任意一塊網路卡的連線;
INADDR_LOOPBACK, 也就是繫結地址LOOPBAC, 往往是127.0.0.1, 只能收到127.0.0.1上面的連線請求

 

 

注意:

 

一個埠可以用於多個連線(比如多個客戶端連線伺服器的同一埠)。但是在同一個作業系統上,即伺服器和客戶端都是本機上,多個客戶端去連線伺服器,只有第一個客戶端的連線會被接收,第二個客戶端的連線請求不會被接收。

 

首先,伺服器和客戶端都可以bind,bind並不是伺服器的專利。
客戶端程式bind埠: 由程式選擇一個埠去連伺服器,(如果預設情況下,呼叫bind函式時,核心指定的埠是同一個,那麼執行多個呼叫了bind 的client 程式,會出現埠被佔用的錯誤)注意這裡的埠是客戶端的埠。如果不分配就表示交給核心去選擇一個可用埠。
客戶程式bind IP地址:相當於為傳送出去的IP資料包分配了源IP地址,但交給程式分配IP地址的時候(就是這樣寫明瞭bind IP地址的時候)這個IP地址必須是主機的一個介面,不能分配一個不存在的IP。如果不分配就表示由核心根據所用的輸出介面來選擇源IP地址。

 

 

相關文章