1. 程式人生 > >網路通訊socket連線數上限

網路通訊socket連線數上限

轉載自http://blog.csdn.net/tgxallen/article/details/54947523

http://www.cppblog.com/aa19870406/archive/2012/07/15/183595.html

as you know,一個socket是由一個五元組來唯一標示的,即(協議,server_ip, server_port, client_ip, client_port)。只要該五元組中任何一個值不同,則其代表的socket就不同。這裡忽略協議的區別,在同一協議的基礎上,伺服器端的listen socket的埠可以看成(server_ip, server_port, ***, ***),其中***是萬用字元,它跟任何一個client_ip, client_port值都不同,可以簡單看成是(0,0)對,當然實現不是這樣的。這樣在伺服器端accept之後,返回的連線socket的四元組就是(server_ip, server_port, client_ip, client_port),這裡的client_ip,client_port因連線的客戶端的不同而不同。所以accept返回的socket和listen socket是不同的,不同之處就在於四元組中的客戶端ip和port,而伺服器端的server_ip和server_port還是相同的,也就是accpet()函式返回的新的socket描述符的埠和listen埠是一樣的。可以使用getsockname()函式來檢視它們之間的不同。

http://blog.csdn.NET/hanzengyi/article/details/5365029

accept是又產生一個Socket埠嗎?

      要寫網路程式就必須用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://blog.csdn.Net/zztfj/article/details/10103621http://blog.csdn.net/zztfj/article/details/10103621

 單機最大的TCP連線數及其修改
一個誤解: 單個伺服器程式可承受最大連線數“理論”上是“65535” .

   65535這個數字的由來,很多人想當然地將它與port最大值聯絡起來。的確,TCP的埠數,最大值確實為65535。但是,這並不代表一個伺服器可以接受的連線數就是這個值。很多人之所以把這兩個概念搞混淆是因為對socket和port沒有更深的認識和理解。我們先來回想一下伺服器服務的先後過程:
1、伺服器建立監聽socket
2、與對外服務的埠號繫結
3、開始listen
4、客戶端連線到伺服器對應的port
5、伺服器accept為新的客戶端產生新的socket
6、基於這個新的socket與客戶端交換資料。
從以上流程來看,最大值為65535的“埠號”這個重要的東東,我們只用了一次,就是執行bind的時候!而以後建立的socket,說白了就是一個可以進行網路IO操作的HANDLE而已。通過檢視該HANDLE的RemoteEndPoint能檢視到遠端客戶端連線的IP和埠號(注意,該埠是遠端客戶端的埠),檢視該HANDLE的LocalEndPoint能看到該Socket的Ip和埠就是該服務繫結的IP和埠。所以,accept的socket值與埠號無關,又何來65535的“理論”上限?

好了,已經弄明白了伺服器端接收的客戶端連線連線數不受最大埠號65535的限制。但是,在客戶端,應用程式最多可以建立多少個TCP連線呢?以及如何調整系統引數來調整單機的最大TCP連線數。

Windows 下單機的TCP連線數有多個引數共同決定,下面一一介紹:

最大TCP連線數
[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]
TcpNumConnections = 0x00fffffe (Default = 16,777,214)

以上登錄檔資訊配置單機的最大允許的TCP連線數,預設為 16M。這個數值看似很大,這個並不是限制最大連線數的唯一條件,還有其他條件會限制到TCP 連線的最大連線數。

最大動態埠數
TCP客戶端和伺服器連線時,客戶端必須分配一個動態埠,預設情況下這個動態埠的分配範圍為 1024-5000 ,也就是說預設情況下,客戶端最多可以同時發起3977 個Socket 連線。我們可以修改如下注冊表來調整這個動態埠的範圍

[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]
MaxUserPort = 5000 (Default = 5000, Max = 65534)

最大TCB 數量
系統為每個TCP 連線分配一個TCP 控制塊(TCP control block or TCB),這個控制塊用於快取TCP連線的一些引數,每個TCB需要分配 0.5 KB的pagepool 和 0.5KB 的Non-pagepool,也就說,每個TCP連線會佔用 1KB 的系統記憶體。

系統的最大TCB數量由如下注冊表設定決定

[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]
MaxFreeTcbs = 2000 (Default = RAM dependent, but usual Pro = 1000, Srv=2000)

非Server版本,MaxFreeTcbs 的預設值為1000 (64M 以上實體記憶體)

Server 版本,這個的預設值為 2000。

也就是說,預設情況下,Server 版本最多同時可以建立並保持2000個TCP 連線。

最大TCB Hash table 數量
TCB 是通過Hash table 來管理的,下面登錄檔設定決定了這個Hash table 的大小

HKEY_LOCAL_MACHINE \System \CurrentControlSet \services \Tcpip \Parameters]
MaxHashTableSize = 512 (Default = 512, Range = 64-65536)

這個值指明分配 pagepool 記憶體的數量,也就是說,如果MaxFreeTcbs = 1000 , 則 pagepool 的記憶體數量為 500KB

那麼 MaxHashTableSize 應大於 500 才行。這個數量越大,則Hash table 的冗餘度就越高,每次分配和查詢 TCP  連線用時就越少。這個值必須是2的冪,且最大為65536.

IBM WebSphere Voice Server 在windows server 2003 下的典型配置
這是IBM WebSphere Voice Server 的典型配置,大家可以做個參考。原文參見

IBM Web Sphere Voice Server 配置

•MaxUserPort = 65534 (Decimal)
•MaxHashTableSize = 65536 (Decimal)
•MaxFreeTcbs = 16000 (Decimal) 
這裡我們可以看到 MaxHashTableSize 被配置為比MaxFreeTcbs 大4倍,這樣可以大大增加TCP建立的速度。

http://www.zhihu.com/question/30772664

單個連線消耗記憶體的地方.

第一個首先是socket buffer. read 和write 分別有一個, 預設大小在
  • /proc/sys/net/ipv4/tcp_rmem (for read)
  • /proc/sys/net/ipv4/tcp_wmem (for write)
預設大小都是87K和16K, 最低是4K和4K, 最高是2M,2M, 實際使用預設值最低也要保留8K,8K.

然後是邏輯IO緩衝區
就是比如你監聽了recv事件 事件來了 你要有記憶體可用(一般都是socket建立起就分配好,斷開才會釋放的).
這個記憶體是自己寫socket程式時候自己控制的, 最低也要4K,4K, 實際使用8K,8K至少.

現在設定一個優化方案和使用場景, 首先假設4G記憶體全部為空閒(系統和其他程序也要記憶體的....

假如網路包的大小都可以控制在4K以下, 假設所有連線的網路都不會擁堵, 或者擁堵時候的總量在4K以下:
一個連線的記憶體消耗是4+4+4+4=16K
4G/16K=26.2萬併發

假如網路包的大小都可以控制在8K以下, 假設所有連線的網路都不會擁堵, 或者擁堵時候的總量在8K以下
一個socket的記憶體佔用介於 24K ~ 32K之間, 保守的按照32K算 
4G/32K=13.1萬併發, 這個在生產環境作為一個純網路層面的記憶體消耗, 是可以作為參考的.

假如使用預設配置, 假如所有連線的網路都出現嚴重擁堵, 不考慮邏輯上的傳送佇列的佔用,
使用預設配置是2M+2M+8+8 ~= 4M
4G/4M=1024併發 ( ...
如果考慮到傳送佇列也擁堵的話 自己腦補.


如果只是為了跑分 為了併發而優化, 沒有常駐的邏輯緩衝區 並且socket的網路吞吐量很小並且負載平滑, 把socket buffer size設定系統最低.
那麼是
4G/8K = 52.4萬併發 這個應該是極限值了.

相關推薦

網路通訊socket連線上限

轉載自http://blog.csdn.net/tgxallen/article/details/54947523 http://www.cppblog.com/aa19870406/archive/2012/07/15/183595.html as you kno

網路通訊Socket+Protobuf協議

不多說了,直接貼程式碼 大家好,如果做即時通訊,相信大家對socket也有一定的瞭解,下面主要是對socket長連線,資料封包解包,外加protobuf的例子,希望能對各位有所幫助 import java.io.BufferedReader; import java.

網路通訊——socket(TCP/IP).Http,同步和非同步的區別

1首先說下同步和非同步的區別吧 同步:提交請求->等待伺服器處理->處理完畢返回 這個期間客戶端瀏覽器不能幹任何事 (比如 普通B/S模式) 非同步:請求通過事件觸發->伺服器處理

java 網路通訊socket實現簡單例項

Socket通訊的步驟                  ① 建立ServerSocket和Socket                  ② 開啟連線到Socket的輸入/輸出流          

作業系統與socket連線限制備忘錄

詳細解釋請檢視記錄來源 1:Linux單機 記錄來源:http://soft.chinabyte.com/os/285/12349285.shtml 一)核心限制 a)核心初始化區間 修改或新增/etc/sysctl.conf net.ipv4.ip_local_port_

18 11 11 網路通訊大都使用的方式 socket

---恢復內容開始--- 瀏覽器  和 聊天工具  一般都用socket   socket  在不同的  語言中的使用流程都大同小異    收  發  關閉 import socket def len():

Tomcat 連線與執行緒池詳解 | BIO/NIO有何不同 | 簡談Kafka中的NIO網路通訊模型

前言 在使用tomcat時,經常會遇到連線數、執行緒數之類的配置問題,要真正理解這些概念,必須先了解Tomcat的聯結器(Connector)。 在前面的文章 詳解Tomcat配置檔案server.xml 中寫到過:Connector的主要功能,是接收連線請求,建立Req

【轉載】網絡通信socket連接上限

建立連接 ont target udp 轉載 函數接口 tails 一個 處理方式 http://blog.csdn.net/tgxallen/article/details/54947523 http://www.cppblog.com/aa19870406/archiv

linux 網路連線檢視方法

1、檢視系統tcp連線中各個狀態的連線數。 netstat -an|awk '/^tcp/ {++s[$NF]} END {for(a in s ) print a,s[a]}' 2、檢視和本機23埠建立連線並狀態在established的所有ip netstat -an|grep

Linux下高併發socket最大連線各種限制的調優

1、修改使用者程序可開啟檔案數限制  在Linux平臺上,無論編寫客戶端程式還是服務端程式,在進行高併發TCP連線處理時,最高的併發數量都要受到系統對使用者單一程序同時可開啟檔案數量的限制(這是因為系統為每個TCP連線都要建立一個socket控制代碼,每個socket控制代碼同時也是一個檔案控制代碼)。可使用

day 26 C/S架構, 網路通訊流程, 初識socket

   1.  C/S 架構 : client 客戶端/ sever 服務端   軟體c/s架構:  QQ, 微信, 瀏覽器等, 其中中瀏覽器又比較特殊,很多網站是基於瀏覽器來進行訪問的,瀏覽器和各個網站服務端進行的通訊方式又常被成為B\S架構(瀏覽器英文名稱:Brow

java網路通訊Socket通訊:TCP/UDP

網路通訊三要素:協議,IP,埠。七層協議。 package com.qianfeng.test; /* * 網路程式設計基礎: * 網路的通訊:三要素:協議,IP,埠 * 1.IP:在網路上唯一的標記一臺主機 127.0.0.1 :保留地址/本地地址 java

高效能跨平臺網路通訊框架 HP-Socket v5.4.2

專案主頁 : http://www.oschina.net/p/hp-socket 開發文件 : http://www.docin.com/p-2137713732.html 下載地址 : https://github.com/ldcsaa/HP-Socket

高效能跨平臺網路通訊框架 HP-Socket v5.4.1

專案主頁 : http://www.oschina.net/p/hp-socket 開發文件 : http://www.docin.com/p-2129383071.html 下載地址 : https://github.com/ldcsaa/HP-Socket

Android Socket連線,使用Socket進行通訊(Android)

一。伺服器程式 伺服器程式需要在PC上執行,該程式比較的簡單,因此不需要建立Android專案,直接定義一個JAVA類,並且執行該類即可。它僅僅建立ServerSocket監聽,並使用Socket獲取輸入輸出流。 SimpleServer import java.io.IOEx

socket通訊顯示連線被拒絕問題總結

socket通訊方式         通常使用的是socket通訊模式為c/s模式,就是通過服務端建立連線,並繫結監聽相關的埠,客戶端通過連線至相應的埠,實現使用tcp的三次握手來進行可靠性連線,從而達到資料傳輸。如果對應的客戶端和服務端在同一臺伺服器上,因是資料內部通訊方

Hololens之Socket網路通訊

我用HoloLens開發網路模組時,最初的做法是用.Net的System.Net.Scoekt中的UDP,想必這個方法是大多數開發者直接想到的方法。但是在匯出時就出問題了,匯出為UWP時,報錯,大致是Socket庫裡缺少某個方法,還有我當時用的同步方法,所以自己寫的的多執行緒

JAVA中Socket服務端和客戶端網路通訊簡單案例

一. 簡單介紹下Socket的用途: 1.Java最初是作為網路程式語言出現的,其對網路提供了高度的支援,使得客戶端和伺服器的溝通變成了現實,而在網路程式設計中,使用最多的就是Socket。像大家熟悉的QQ、MSN都使用了Socket相關的技術 2.IP地址+埠號組成了所

網路通訊之檢測遠端連線是否斷開連線

判斷對方是否斷開連線: 一、方法層面的實現:   1,使用輸入流的read方法:     輸入流的read(byte[] ,int ,int) 方法,表示從當前的通道中讀取資料,具體讀取到的資料有返回的int值決定;這裡的返回值和丟擲的異常很重要,如果丟擲IOException異常,很明顯連線已經斷開;   

socket跟TCP/IP 的關係,單臺伺服器上的併發TCP連線可以有多少

常識一:檔案控制代碼限制 在linux下編寫網路伺服器程式的朋友肯定都知道每一個tcp連線都要佔一個檔案描述符,一旦這個檔案描述符使用完了,新的連線到來返回給我們的錯誤是“Socket/File:Can'topen so many files”。 這時你需要明白作業系統對可以開啟的最大檔案數