socket跟TCP/IP 的關系,單臺服務器上的并發TCP連接數可以有多少

常識一:文件句柄限制

在linux下編寫網絡服務器程序的朋友肯定都知道每一個tcp連接都要占一個文件描述符,一旦這個文件描述符使用完了,新的連接到來返回給我們的錯誤是“Socket/File:Can'topen so many files”

這時你需要明白操作系統對可以打開的最大文件數的限制。

  • 進程限制

    • 執行ulimit -n 輸出1024,說明對于一個進程而言最多只能打開1024個文件,所以你要采用此默認配置最多也就可以并發上千個TCP連接。

    • 臨時修改:ulimit -n1000000,但是這種臨時修改只對當前登錄用戶目前的使用環境有效,系統重啟或用戶退出后就會失效。

    • 永久修改:編輯/etc/security/limits.conf 文件, 修改后內容為

      * soft nofile 1000000

      * hard nofile 1000000

  • 全局限制

    • 執行 cat/proc/sys/fs/file-nr 輸出9344 0592026,分別為:1.已經分配的文件句柄數,2.已經分配但沒有使用的文件句柄數,3.最大文件句柄數。但在kernel2.6版本中第二項的值總為0,這并不是一個錯誤,它實際上意味著已經分配的文件描述符無一浪費的都已經被使用了 。

    • 我們可以把這個數值改大些,用 root 權限修改 /etc/sysctl.conf 文件:

      fs.file-max = 1000000

      net.ipv4.ip_conntrack_max = 1000000

      net.ipv4.netfilter.ip_conntrack_max = 1000000

常識二:端口號范圍限制?

操作系統上端口號1024以下是系統保留的,從1024-65535是用戶使用的。由于每個TCP連接都要占一個端口號,所以我們最多可以有60000多個并發連接。我想有這種錯誤思路朋友不在少數吧?(其中我過去就一直這么認為)

我們來分析一下吧

  • 如何標識一個TCP連接:系統用一個4四元組來唯一標識一個TCP連接:{local ip, local port,remoteip,remoteport}。好吧,我們拿出《UNIX網絡編程:卷一》第四章中對accept的講解來看看概念性的東西,第二個參數cliaddr代表了客戶端的ip地址和端口號。而我們作為服務端實際只使用了bind時這一個端口,說明端口號65535并不是并發量的限制。

  • server最大tcp連接數:server通常固定在某個本地端口上監聽,等待client的連接請求。不考慮地址重用(unix的SO_REUSEADDR選項)的情況下,即使server端有多個ip,本地監聽端口也是獨占的,因此server端tcp連接4元組中只有remoteip(也就是client ip)和remoteport(客戶端port)是可變的,因此最大tcp連接為客戶端ip數×客戶端port數,對IPV4,不考慮ip地址分類等因素,最大tcp連接數約為2的32次方(ip數)×2的16次方(port數),也就是server端單機最大tcp連接數約為2的48次方。


要寫網絡程序就必須用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包的處理規則也是清晰明了,不存在前面設想的種種復雜的情形。


明白socket只是對TCP/IP協議棧操作的抽象,而不是簡單的映射關系,這很重要!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280327.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280327.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280327.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SSPL的MongoDB再被拋棄,GUN Health也合流PostgreSQL

2019 年 2 月 12 日,紅帽官方發博稱,Red Hat Satellite 將擁抱PostgreSQL,并且不會支持 SSPL 許可的 MongoDB 新版本。無獨有偶,同一天GNU Health也發博稱GNU Health Federation Information System 將從MongoDB遷移到PostgreSQL&…

開源的 .NET 數據庫遷移框架

你好,這里是 Dotnet 工具箱,定期分享 Dotnet 有趣,實用的工具和組件,希望對您有用!簡介FluentMigrator 是一個開源的數據庫遷移框架,可以幫助用戶在開發過程中保持數據庫的一致性。它提供了一個簡潔的 Flue…

在deepin上安裝YouCompleteMe

詳細安裝步驟在github上有,https://github.com/Valloric/YouCompleteMe,我這里是自己總結的簡化版安裝步驟。 步驟1.安裝Vundle 首先,clone到本地 git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim把以下內容…

2015年IT領域里Docker和其它顛覆性的趨勢

本文講的是2015年IT領域里Docker和其它顛覆性的趨勢,【編者的話】文中作者介紹了2015年IT領域的一些顛覆性的趨勢,比如Docker將如何革新PaaS、IaaS等,Docker將如何顛覆虛擬化、私有云、配置管理。 2014年真是令人興奮的一年,這一年…

進化:從孤膽極客到高效團隊_極客狂:為什么這么多的網站無法使用打印樣式表?...

進化:從孤膽極客到高效團隊It never ceases to amaze me that people have to look for a link or a button that says “Print” on a web page, especially considering there’s a miracle technology that makes that step unnecessary. Sadly almost nobody uses it, even…

Iterator 和 for...of 循環

Iterator 和 for...of 循環 Iterator(遍歷器)意義 為Array、Object、Map、Set四種數據集合,提供統一的接口機制來處理所有不同的數據結構 。 任何數據結構,只要部署 Iterator 接口,就可以完成遍歷操作(即依…

python簡單開發接口

1、首先需要安裝flask這個模塊:pip install flask。flask是個輕量級的接口開發框架2、開發接口有什么作用  1、mock接口,模擬一些接口,在別的接口沒有開發好的時候,需要用mock去模擬一些接口。  2、知道接口是怎么開發的&…

九哥聊Kestrel網絡編程第二章:開發一個Fiddler

推薦序之前在.NET 性能優化群內交流時,我們發現很多朋友對于高性能網絡框架有需求,需要創建自己的消息服務器、游戲服務器或者物聯網網關。但是大多數小伙伴只知道 DotNetty,雖然 DotNetty 是一個非常優秀的網絡框架,廣泛應用于各…

apple tv 開發_如何跨多臺Apple TV同步Apple TV的主屏幕

apple tv 開發If you have more than one Apple TV in your household, you probably know how annoying it is when you have to install Apple TV apps multiple times on each device. However, with the release of tvOS 11, that’s no longer the case. 如果您的家庭中有…

這些故事說的都是你——譯者帶你讀《硅谷革命》

作者 | 薛命燈 作為《硅谷革命》的譯者之一,同時也是一個擁有十余年軟件開發和架構經驗的工程師,當時我在決定是否接受重譯這本書的時候,幾乎是不假思索地答應了郭蕾(本書重啟版發起人之一)的提議,只因他的…

runc容器逃逸漏洞最強后續:應對之策匯總與熱點疑問解答

美國時間2019年2月11日晚,runc通過oss-security郵件列表披露了runc容器逃逸漏洞CVE-2019-5736的詳情。runc是Docker、CRI-O、Containerd、Kubernetes等底層的容器運行時,此次安全漏洞無可避免地會影響大多數Docker與Kubernetes用戶,也因此為整…

OOD之問題空間到解空間—附FP的建模

通常會被問到,什么事OOD,然后大部分人期待的答案比較死板,繼承、封裝、多態!懂這個的人多的去了,有什么好問?回答出來的人是否拿著Java又去做一些面向過程的勾當? 計算機革命起源于機器&#xf…

com surrogate_什么是“ COM Surrogate”(dllhost.exe),為什么它在我的PC上運行?

com surrogateIf you poke around in your Task Manager, there’s a good chance you’ll see one or more “COM Surrogate” processes running on a Windows PC. These processes have the file name “dllhost.exe”, and are part of the Windows operating system. You’…

云計算時代,互聯網金融背后的想象空間

本文講的是云計算時代,互聯網金融背后的想象空間,【IT168評論】阿里巴巴在紐交所的開市鐘史無前例的由八位合作伙伴敲響,可見阿里對互聯網時代構筑起生態系統的堅持。這其中,由余額寶所敲開的互聯網金融熱潮的熱度持續不減&#x…

JavaScript數據結構與算法——集合

1.集合數據結構 集合是一組無序且唯一(不能重復)的項組成的。這個數據結構使用了和有限集合相同的數學概念。 2.創建集合 function Set() {// 這里使用對象而不是數組來表示集合 // js對象中不允許一個鍵值指向兩個不同屬性,也保證了集合中的…

php用兩個棧來實現隊列

php用兩個棧來實現隊列 一、總結 我主要的問題是不知道的是題目描述,題目和貴的代碼之間的關系,以及返回值 思路:A棧做入隊操作,B棧做出隊操作,入隊的時候元素直接入A,出隊的時候判斷B棧是否為空&#xff0…

facebook 邀請好友_如何查看緊急情況下您的Facebook朋友是否安全

facebook 邀請好友Facebook’s Safety Check feature lets you check in during an emergency to confirm you’re safe. If you have friends or family in an area that you haven’t heard from, though, you may want to ask them directly. Here’s how to ask someone to…

【您有一封來自阿里云的邀請函】阿里云成都客戶服務中心20+職位虛席以待,來吧,成就最好的自己!...

如果你不想辜負這個科技的時代,相信它會因你而不同。如果你不想僅做年度大戲的觀眾,相信自己會成為主角。如果你不想淹沒在枯燥與茍且中,相信工作有詩和遠方。那么,不要猶豫,加入我們!在這,你已…

A - A Secret -擴展KMP

題目大意:給你兩個字符串A,B,現在要你求B串的后綴在A串中出現的次數和后綴長度的乘積和為多少。題解:擴展KMP模板題,將A和B串都逆序以后就變成了求前綴的問題了,擴展KMP求處從i位置開始的最長公共前綴存于數組。最后通…

.NET 代碼優化 聊聊邏輯圈復雜度

本文屬于 dotnet 代碼優化系列博客。相信大家都對圈復雜度這個概念很是熟悉,本文來和大家聊聊邏輯的圈復雜度。代碼優化里面,一個關注的重點在于代碼的邏輯復雜度。一段代碼的邏輯復雜度越高,那么維護起來的難度也就越大。衡量代碼的邏輯復雜…