亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

談談網絡編程里的那些事

2019-11-14 16:42:45
字體:
來源:轉載
供稿:網友

網絡編程一直是經久不衰的話題,今天就網絡編程里面一些問題做個總結,由于UDP相對于TCP的處理問題比較簡單,所以這次總結的都是有關TCP的。

一、關于服務器最大TCP連接數問題。

       很多人認為單臺服務器的最大TCP連接數是65536也就是受限于服務器的端口的數量 如果服務器想開6W以上的TCP連接就要綁定多個ip。其實這是一個重大的錯誤認識,其實按照TCP/IP協議的規定,確定一個連接的唯一標識是一個4元組 <本地IP,本地端口,遠程IP,遠程端口>,因為服務器綁定的端口和IP是固定的(一般進程都只綁定一個端口和IP),所以決定連接的因素就是客戶機器的遠程IP和遠程端口 ,與服務器端口數量根本沒有任何關系,也就是說客戶機的IP范圍和端口號范圍才是決定連接的重要因素,我們知道IP地址的范圍是2^32個(這里IP和端口不考慮保留問題),端口的數量是2^16個 那么服務器保持的最大連接數的理論值是2^32*2^16=2^48  。不過,難道服務器端真的能開那么多連接么,答案是要看服務器有多少物理內存。也就是說物理內存的大小才是決定服務器能開多少連接的決定因數(當然也和操作系統的設置有關 例如:最大文件句柄的數量,但總體來說是受限于物理內存),如果只有1G的物理內存想開100W的連接這是不可能的。我們知道建立一個socket連接和打開一個文件一樣,是由操作系統建立一個文件句柄,文件句柄指向一個稱為文件對象的windows內核對象 ,創建文件對象的數量決定了TCP的最大連接數,也可以這么認為:對于有限的資源 服務器最大的TCP連接數是操作系統能打開文件的最大數量,如果系統資源足夠大時那么最大就是2^48。

       為了證明服務端的I連接數P和端口沒有關系   我寫了一個測試程序,該程序為了屏蔽線程棧消耗的內存采用了.net 封裝好的IOCP的方式。

       客戶端測試機使用了3臺普通的PC機 ,三臺臺器分別與服務器保持5W,4W,1W個連接,統計服務端的連接數是否是10W。

      程序代碼如下:

   1. 服務端代碼:

    /// <summary>    /// IOCP soket    /// </summary>    class Server    {        PRivate Socket connSocket;        //統計連接總數        private static int count;        public  Server()        {                    connSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);            IPAddress ip = IPAddress.Parse("192.168.1.123");            IPEndPoint endPoint = new IPEndPoint(ip, 6530);                        connSocket.Bind(endPoint);            connSocket.Listen(50000);            }        /// <summary>        /// 接收客戶端連接        /// </summary>        public void Start()        {            IAsyncResult acceptResult=null;            acceptResult = connSocket.BeginAccept(AcceptCallback, connSocket);        }             private void AcceptCallback(IAsyncResult ar)        {            Socket accetpSocket = ar.AsyncState as Socket;            if(accetpSocket==null)            {                return;            }            Socket  receiveSocket= accetpSocket.EndAccept(ar);            //打印連接數            count++;            Console.WriteLine("連接數:{0}",count);            Start();            Receieve(receiveSocket);           }        /// <summary>        /// 接收發送的數據        /// </summary>        /// <param name="receiveSocket">接收數據的socket</param>        private void Receieve(Socket receiveSocket)        {            byte[] buffer = new byte[28];            receiveSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, (state) =>            {                Socket receive = state.AsyncState as Socket;                try                {                    int length = receive.EndReceive(state);                    Console.WriteLine(Encoding.Unicode.GetString(buffer));                    Receieve(receive);                }                catch (SocketException socketEx)                {                    receive.Dispose();                }            }, receiveSocket);        }     }

     2. 客戶端代碼:

   /// <summary>    /// 測試客戶端    /// </summary>    class Program    {        static List<Socket> socketList = new List<Socket>();            static void Main(string[] args)        {                       for (int i = 0; i < 40000;i++)            {                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                                int port = 6530;                IPAddress ip = IPAddress.Parse("192.168.1.123");//本地                socket.Connect(ip, port);                socketList.Add(socket);            }            Console.ReadKey();        }    }

   3.測試結果:  

      (1)Server運行結果:

          2

                                                                                        圖3.1

        (2)Tcpview監視的連接:

          1

                                                                                 圖3.2

(3)server占用資源情況:

         3

                                                                                                     圖3.3

     

          根據圖3.1的結果可以看出, 服務端接受的連接數為10W ,所以說 最大TCP連接數與服務端的端口的數量沒關系,而且根據圖3.2得知服務端的端口是保持不變的,變的只是客戶端的IP和端口,所以一個連接的唯一標識就是一個4元組 <本地IP,本地端口,遠程IP,遠程端口>。

          進一步分析,我們假定該程序所有的內存都是連接占用的,根據圖3.3可以看出10W個連接占用了 200 M內存,也就是每個連接占用了 2kb   在物理內存4G的32操作系統下開起連接數最大約為100W(用戶模式使用了2G的尋址空間),但是即使有4G的物理內存也未必能開啟50W個連接,因為在內核模式的地址空間分為分頁內存池和非分頁內存池(用戶模式下總是分頁的),文件對象這個windows內核對象是存儲在內核模式下的非分頁內存池,所謂非分頁內存池就是該內存區始終在物理內存而不會在磁盤文件的頁交換文件中,而內核模式的分頁內存池也占用了一部分物理內存,導致整個內核模式的非分頁內存池不能達到2G,所以100W個連接在32位操作系統是也無法開啟。那么在64位操作系統上,理論上內存大的話是沒有限制的,亞馬遜曾經測試過node.js的連接數 100W個連接占用了16G的內存(.net程序沒有測過100W的內存情況,所以4G的100W個連接只是推測,和實際情況可能差別較大) http://blog.caustik.com/2012/08/19/node-js-w1m-concurrent-connections/。

         最后還要補充一句:服務器的性能和處理多少連接數沒關系,即使100W個連接只是連接而不發送數據,服務器只是浪費點內存,如果100W個同時發送數據,那么服務器可能會處理不過來,處理不過來只是相對于而言,如果發送的每個連接消息非常小,服務器的配置好,而且服務端處理消息的邏輯相對簡單,那可能會處理過來,相反 一個連接只發送一條消息,但服務器處理這條消息的邏輯非常復查,比如要做個幾分鐘的大型的計算,那么服務器也是處理不過來的。所以對于服務端來說 一味的追求多少連接數是不可取的,主要還是要衡量處理消息的邏輯。

二、關于TCP多個連接比一個連接快的問題

   TCP/IP協議限制了每個連接的最大傳輸速度。而且使各大連接的速度保持一直,所以說不考慮服務端的處理速度等其他因數,多個連接的發送數據速度要比單個連接的快,所以迅雷采用了多線程下載的方式。當然,我們實際開發中要采用多少個連接需要根據服務端對每個連接的處理能力進行測算,找出一個平衡點。

三、關于處理字節序的問題

              在.net平臺之間進行通訊時可以忽略主機字節序的問題,.net平臺統一采用了小端法,如果需要跨平臺傳輸,就需要統一字節序,一般有兩種方案:

               1.采用字符串的形式,注意UNICODE編碼的字符串占2個字節,所以同樣會有字節序的問題,所以應該使用ANSCI的字符串。

     2.都采用大端或小端,在報文里用一個字節做個表識來表明主機的字節序。

四、關于處理TCP斷包和粘包的問題

             因為TCP屬于流式傳輸,所以沒有數據邊界,所以我們不知道每次發送數據的長度,所以每次接受數據時可能是兩個包或者可能是一個不完整的包,這就我們需要處理TCP斷包和粘包這兩個場景,一般解決方案是在頭部前4個字節來標識整個數據包的長度,接受數據時先接受4個字節的長度,然后根據解析出的包長進行循環接收直到數據包接完整為止,注意接收前4個字節的包長是也要進行循環接受直到接滿4個字節。

           有時候數據包傳輸過程中會出現錯誤,一般都是校驗CRC是否完整來校驗包的正確性。一旦數據包出現錯誤一般有兩種測試處理:第一是直接丟棄整個包, 該方法簡單但可能會失去某些比較重要的數據。 第二個是對根據報文對整個包進行遍歷把可能沒有錯誤的數據保持下來,但是該方案比較麻煩。

 

           最后一句感言:無論什么平臺和語言,基礎知識都是通用的,制約發展的因素不是我們會哪幾種語言,而是我們運用基礎知識去解決實際問題的能力。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品在线观看一区二区| 欧美极度另类性三渗透| 国产精品激情av在线播放| 亚洲国产精品国自产拍av秋霞| 欧美专区在线播放| 国产精品福利小视频| 成人欧美一区二区三区在线| 97久久久免费福利网址| 亚洲毛片在线免费观看| 久久视频在线看| 国产精品一区二区三区毛片淫片| 国产精品18久久久久久首页狼| 精品呦交小u女在线| 国产精品白嫩初高中害羞小美女| 亚洲精品在线看| 欧美大全免费观看电视剧大泉洋| 亚洲免费中文字幕| 亚洲国产精品免费| 国产成人一区二区在线| 国产精品海角社区在线观看| 亚洲新声在线观看| 国产suv精品一区二区三区88区| 久久亚洲综合国产精品99麻豆精品福利| 欧美激情精品久久久| 亚洲精品理论电影| 久久国产精品免费视频| 91在线精品播放| 亚洲深夜福利在线| 日韩中文字幕网址| 成人激情视频在线| 日韩成人激情视频| 日韩高清电影免费观看完整| 中文字幕欧美视频在线| 久久香蕉国产线看观看网| 亚洲精品一区久久久久久| 国产日韩欧美在线| 欧美在线观看日本一区| 最近2019年中文视频免费在线观看| 亚洲欧美成人一区二区在线电影| 亚洲最大的网站| 国产精品电影一区| 欧美激情小视频| 一区二区三区四区精品| 亚洲欧美日韩精品久久奇米色影视| 午夜精品一区二区三区在线视频| 91免费在线视频| 欧美成人在线免费| 日韩一区av在线| 成人国产精品免费视频| 91av中文字幕| 国产精品三级在线| 亚洲免费精彩视频| 91美女高潮出水| 日韩在线视频观看正片免费网站| www.欧美三级电影.com| 亚洲成人久久久| 久久精品国产一区二区三区| 欧美日韩视频在线| 亚洲石原莉奈一区二区在线观看| 日韩av网址在线观看| 亚洲乱码av中文一区二区| 久久偷看各类女兵18女厕嘘嘘| 在线观看国产精品日韩av| 久久99热这里只有精品国产| 日韩免费观看视频| 亚洲国产日韩欧美在线图片| 欧美乱大交做爰xxxⅹ性3| 国产亚洲精品高潮| 国产精品久久久一区| 国产午夜精品美女视频明星a级| 久久影视电视剧凤归四时歌| 欧美激情日韩图片| 在线播放亚洲激情| 国产精品视频免费在线| 国模精品系列视频| 成人网中文字幕| 日韩精品高清在线观看| 久久精品国产久精国产思思| 91精品国产自产在线观看永久| 国产成人精品久久亚洲高清不卡| 狠狠色噜噜狠狠狠狠97| 国产成人精品网站| 国产精品视频网址| 国产在线观看精品| 高清亚洲成在人网站天堂| 日韩免费高清在线观看| www.欧美精品一二三区| 欧美国产日韩xxxxx| 中文字幕精品久久| 国产成人午夜视频网址| 色综合导航网站| 国产精品亚洲片夜色在线| 欧美香蕉大胸在线视频观看| 久久久久久久久久久91| 亚洲天堂2020| 色午夜这里只有精品| 亚洲精品国产成人| 亚洲国产中文字幕久久网| 伊人精品在线观看| 国产精品入口夜色视频大尺度| 性欧美xxxx| 亚洲国产美女精品久久久久∴| 国产ts一区二区| 日韩中文字幕av| 91九色精品视频| 欧美成人免费在线视频| 欧美理论电影在线观看| 日韩精品一区二区三区第95| 国产精品99久久久久久人| 国产精品男女猛烈高潮激情| 91久久久久久国产精品| 成人精品在线观看| 亚洲性生活视频在线观看| 青青在线视频一区二区三区| 国产精品视频在线播放| 国产精品久久久久久久久免费看| 国产精品一区二区在线| 欧美男插女视频| 国产区精品在线观看| 国产一区视频在线播放| 91久久夜色精品国产网站| 国产91色在线|| 神马久久桃色视频| 欧美性高跟鞋xxxxhd| 国产精品免费在线免费| 国产精品久久久久久久久借妻| 日韩欧美在线视频观看| 国产精品扒开腿做| 久久九九亚洲综合| 最新国产成人av网站网址麻豆| 欧美日韩国产二区| 日本免费一区二区三区视频观看| 亲子乱一区二区三区电影| 久久天天躁狠狠躁夜夜躁| 欧美视频中文字幕在线| 91大神在线播放精品| 久久视频国产精品免费视频在线| 久久成人在线视频| 久久99热精品| 欧美视频裸体精品| 国产欧美亚洲视频| 日韩精品视频免费专区在线播放| 国产精品第3页| 久久久91精品| 18性欧美xxxⅹ性满足| 97精品免费视频| 日韩av网站导航| 亚洲一二在线观看| 亚洲一区免费网站| 国产亚洲日本欧美韩国| 97视频在线观看免费| 亚洲精品国产精品国自产在线| 91久久精品美女高潮| 免费99精品国产自在在线| 国产一区二区三区视频在线观看| 亚洲伦理中文字幕| 欧美日韩第一视频| 草民午夜欧美限制a级福利片| 久久电影一区二区| 日韩性xxxx爱| 国产精品自拍小视频| 日韩精品在线免费观看视频| 国产一区香蕉久久| 亚洲香蕉伊综合在人在线视看|