TCP伺服器乙個埠號可以有多個連線

2021-09-08 16:15:23 字數 2328 閱讀 4457

這是我在討論區看到的乙個回答,寫的很好,讓我明白了為什麼單個伺服器程式可承受最大連線數可以達到幾十w

要寫網路程式就必須用socket,這是程式設計師都知道的。而且,面試的時候,我們也會問對方會不會socket程式設計?一般來說,很多人都會說,socket程式設計基本就是listen,accept以及send,write等幾個基本的操作。是的,就跟常見的檔案操作一樣,只要寫過就一定知道。

對於網路程式設計,我們也言必稱tcp/ip,似乎其它網路協議已經不存在了。對於tcp/ip,我們還知道tcp和udp,前者可以保證資料的正確和可靠性,後者則允許資料丟失。最後,我們還知道,在建立連線前,必須知道對方的ip位址和埠號。除此,普通的程式設計師就不會知道太多了,很多時候這些知識已經夠用了。最多,寫服務程式的時候,會使用多執行緒來處理併發訪問。

我們還知道如下幾個事實:

1。乙個指定的埠號不能被多個程式共用。比如,如果iis占用了80埠,那麼apache就不能也用80埠了。

2。很多防火牆只允許特定目標埠的資料報通過。

3。服務程式在listen某個埠並accept某個連線請求後,會生成乙個新的socket來對該請求進行處理。

於是,乙個困惑了我很久的問題就產生了。如果乙個socket建立後並與80埠繫結後,是否就意味著該socket占用了80埠呢?如果是這樣的,那麼當其accept乙個請求後,生成的新的socket到底使用的是什麼埠呢(我一直以為系統會預設給其分配乙個空閒的埠號)?如果是乙個空閒的埠,那一定不是80埠了,於是以後的tcp資料報的目標埠就不是80了--防火牆一定會組織其通過的!實際上,我們可以看到,防火牆並沒有阻止這樣的連線,而且這是最常見的連線請求和處理方式。我的不解就是,為什麼防火牆沒有阻止這樣的連線?它是如何判定那條連線是因為connet80埠而生成的?是不是tcp資料報裡有什麼特別的標誌?或者防火牆記住了什麼東西?

後來,我又仔細研讀了tcp/ip的協議棧的原理,對很多概念有了更深刻的認識。比如,在tcp和udp同屬於傳輸層,共同架設在ip層(網路層)之上。而ip層主要負責的是在節點之間(end to end)的資料報傳送,這裡的節點是一台網路裝置,比如計算機。因為ip層只負責把資料送到節點,而不能區分上面的不同應用,所以tcp和udp協議在其基礎上加入了埠的資訊,埠於是標識的是乙個節點上的乙個應用。除了增加埠資訊,upd協議基本就沒有對ip層的資料進行任何的處理了。而tcp協議還加入了更加複雜的傳輸控制,比如滑動的資料傳送視窗(slice window),以及接收確認和重發機制,以達到資料的可靠傳送。不管應用層看到的是怎樣乙個穩定的tcp資料流,下面傳送的都是乙個個的ip資料報,需要由tcp協議來進行資料重組。

所以,我有理由懷疑,防火牆並沒有足夠的資訊判斷tcp資料報的更多資訊,除了ip位址和埠號。而且,我們也看到,所謂的埠,是為了區分不同的應用的,以在不同的ip包來到的時候能夠正確**。

tcp/ip只是乙個協議棧,就像作業系統的執行機制一樣,必須要具體實現,同時還要提供對外的操作介面。就像作業系統會提供標準的程式設計介面,比如win32程式設計介面一樣,tcp/ip也必須對外提供程式設計介面,這就是socket程式設計介面--原來是這麼回事啊!

在socket程式設計介面裡,設計者提出了乙個很重要的概念,那就是socket。這個socket跟檔案控制代碼很相似,實際上在bsd系統裡就是跟檔案控制代碼一樣存放在一樣的程序控制代碼表裡。這個socket其實是乙個序號,表示其在控制代碼表中的位置。這一點,我們已經見過很多了,比如檔案控制代碼,視窗控制代碼等等。這些控制代碼,其實是代表了系統中的某些特定的物件,用於在各種函式中作為引數傳入,以對特定的物件進行操作--這其實是c語言的問題,在c++語言裡,這個控制代碼其實就是this指標,實際就是物件指標啦。

現在我們知道,socket跟tcp/ip並沒有必然的聯絡。socket程式設計介面在設計的時候,就希望也能適應其他的網路協議。所以,socket的出現只是可以更方便的使用tcp/ip協議棧而已,其對tcp/ip進行了抽象,形成了幾個最基本的函式介面。比如create,listen,accept,connect,read和write等等。

現在我們明白,如果乙個程式建立了乙個socket,並讓其監聽80埠,其實是向tcp/ip協議棧宣告了其對80埠的占有。以後,所有目標是80埠的tcp資料報都會**給該程式(這裡的程式,因為使用的是socket程式設計介面,所以首先由socket層來處理)。所謂accept函式,其實抽象的是tcp的連線建立過程。accept函式返回的新socket其實指代的是本次建立的連線,而乙個連線是包括兩部分資訊的,乙個是源ip和源埠,另乙個是宿ip和宿埠。所以,accept可以產生多個不同的socket,而這些socket裡包含的宿ip和宿埠是不變的,變化的只是源ip和源埠。這樣的話,這些socket宿埠就可以都是80,而socket層還是能根據源/宿對來準確地分辨出ip包和socket的歸屬關係,從而完成對tcp/ip協議的操作封裝!而同時,放火牆的對ip包的處理規則也是清晰明了,不存在前面設想的種種複雜的情形。

埠號,乙個埠號是否可以被多個程序使用?

1.埠號的作用 埠號可以用來標識同乙個主機上通訊的不同應用程式,埠號 ip位址就可以組成乙個套接字,用來標識乙個程序 2.埠號的應用場景 在tcp ip協議中,用 源ip位址 目的ip位址 源埠號 目的埠號 協議號 ip協議的協議號為4,tcp的協議號為6 這樣的乙個五元組來標識乙個通訊,通訊的雙方...

修改伺服器遠端埠號

修改預設3389埠有兩種方法 方法一 手動修改登錄檔檔案,注意要修改2處登錄檔檔案下的portnamber 的鍵值修改埠的登錄檔路徑 路徑一 hkey local machine system currentcontrolset control terminal server wds rdpwd t...

修改伺服器端口號

引用 為了使獨享伺服器遠端登陸更加安全,經常能夠遇到客戶詢問如何修改遠端桌面埠的問題,下面就詳細說明一下具體方法 首先,登陸伺服器選擇系統桌面中的 開始 執行 命令,從彈出的系統執行框中,輸入字串命令 regedit 單擊 確定 按鈕後,開啟本地工作站的系統登錄檔編輯介面 展開hkey local ...