聊一聊服務器和客戶端會話過程中的端口

之前在TCP/IP的網絡通信的學習中,主要關注的都是高併發,高性能的方面,忽略了一些基本的概念,特別是端口這個東西,這個東西在服務器開發過程中可能看起來也不是很麻煩,在服務器上就是一個bind(),在客戶端指定一下目標端口就行了,也沒有太深入理解其中的東西,今天就來好好的總結梳理一下。

還是以服務器和客戶端的會話爲例,什麼是端口呢?如果把IP地址比作一間房子 ,端口就是出入這間房子的門。真正的房子只有幾個門,但是一個IP地址的端口 可以有65536(即:256×256)個之多!端口是通過端口號來標記的,端口號只有整數,範圍是從0 到65535(256×256-1)。端口其實就是隊,操作系統爲各個進程分配了不同的隊,數據包按照目的端口被推入相應的隊中,等待被進程取用,在極特殊的情況下,這個隊也是有可能溢出的,不過操作系統允許各進程指定和調整自己的隊的大小。一個數據包包括了文件,ip,和端口號,ip是爲了服務器可以找到你的主機,端口號是你接受數據包的門戶, 而所謂的端口監聽,是指主機網絡進程接受到IP數據包後,察看其的目標端口是不是自己的端口號,如果是的話就接受該數據包進行處理。


在服務器和客戶端通信過程中,socket通信的雙方自己決定自己要用什麼端口,服務器端只能決定自己listen的是哪個端口,不能決定客戶端的端口;客戶端也只能決定自己的端口,當然,因爲它是主動連接的,所以它知道對方的端口號,但它也不能把對方的服務移到別的端口上面去。端口號是用來區分相同主機上的不同socket的,它相當於socket在本機這一端的名字,一個端口只能bind一次,佔用了之後同時就不能再給別人用了,這麼寶貴的資源都要留給listen的一方,主動連接的一方一般去用那些操作系統隨機分配的端口號。bind也可以指定端口號爲0,這種情況下就是隨機綁定一個沒有使用過的端口號,可以用來在建立連接之前就確定本端的端口號。作爲listen的一方,所有被動建立起來的連接的本端端口都是listen的端口。只有源IP、源端口、目的IP、目的端口還有協議號都完全相同纔會認爲是同一個socket,所以被動建立連接的socket源端口號不同,目的端口號是可以相同的。

我們在linux環境來查看一下端口使用情況:

輸入命令netstat -tunap(-t 表示顯示tcp相關 -u表示顯示udp相關 -n表示拒絕顯示別名,能顯示數字全部轉換爲數字 -a表示顯示所有狀態的,-l則表示顯示listen狀態的 不輸入則表示顯示established狀態的 -p表示顯示建立相關鏈接的程序名),效果如下


在ip地址後的冒號,如這個,0.0.0.0表示ip,表示111端口號。

什麼時候需要使用到端口這個東西呢?

1、採用TCP通信時,客戶端不需要bind()他自己的IP和端口號,而服務器必須要bind()自己本機的IP和端口號;

2、若採用UDP通信時(這裏是有客戶端和服務器之分才這麼說的,若是指定特定端口的UDP對等通信則不一樣了),客戶端也可以不需要bind()他自己的IP和端口號,而服務器需要bind自己IP地址和端口號;

再說下客戶端用不用bind的區別

無連接的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


再說一個問題,爲什麼你用瀏覽器打開一個網站不需要輸入端口呢不是說好客戶端訪問服務器需要指定端口號的嗎?其實,是你的瀏覽器默認幫助你的ip地址後面加上了:80,80端口是默認的http端口,所以就不需要你輸入網址時加端口啦,如果你自己搭建了一個服務器,比如nginx,你把config文件裏的listen端口改成其他端口,你看你的瀏覽器還是否能夠不加端口訪問。

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