那既然是網(wǎng)絡(luò)并發(fā)總是要”發(fā)“的吧,提到發(fā)那還必須先知道是使用合種協(xié)議去發(fā)送,主流的tcp,http等都很常見(jiàn)(通常很少有自己創(chuàng)造一種協(xié)議去進(jìn)行通信的,即使有的公司內(nèi)部的通信協(xié)議一般也是會(huì)基于tcp等基礎(chǔ)傳輸協(xié)議)
現(xiàn)在以tcp協(xié)議為例,既然要發(fā)送那肯定是要先連接起來(lái)的(大多數(shù)協(xié)議都是需要連接的,即便http稱(chēng)是無(wú)連接的,不過(guò)http也是基于tcp的應(yīng)用協(xié)議,所以連接肯定是少不了的,只是連接完成后會(huì)主動(dòng)斷開(kāi)),為了了解連接的過(guò)程先回顧下tcp的握手過(guò)程吧
完成3次握手后連接就算完成了,那問(wèn)題來(lái)了發(fā)送數(shù)據(jù)前要先連接,那連接的數(shù)量有沒(méi)有限制呢,一些觀點(diǎn)認(rèn)為計(jì)算機(jī)端口的數(shù)量限制著連接數(shù)量,這種看法當(dāng)然是不正確的,端口的數(shù)量只是限制著當(dāng)前計(jì)算機(jī)客戶(hù)端的數(shù)量而已。其實(shí)理解這個(gè)東西也十分簡(jiǎn)單,只是一直借助讓我們對(duì)其本身少了很多思考,由操作系統(tǒng)構(gòu)架與傳輸層與應(yīng)用層直接http高并發(fā)測(cè)試工具,它的便利性讓我們對(duì)端口模糊化了。而實(shí)際上在網(wǎng)絡(luò)層的ip包并沒(méi)有端口號(hào)這個(gè)數(shù)據(jù)位,顯然端口其實(shí)是應(yīng)用層面的數(shù)據(jù)分組,操作系統(tǒng)(當(dāng)然包括網(wǎng)絡(luò)設(shè)備的操作系統(tǒng))接收所有數(shù)據(jù),然后根據(jù)數(shù)據(jù)包里面的端口信息決定數(shù)據(jù)的去向,對(duì)于來(lái)說(shuō)上層應(yīng)用程序向系統(tǒng)申請(qǐng)監(jiān)聽(tīng)xxx端口,你們操作系統(tǒng)會(huì)在自己接收到的包中發(fā)現(xiàn)是xxx端口的就會(huì)給前面的應(yīng)用程序一份(還有一點(diǎn)提一下:端口不一定會(huì)被某一個(gè)應(yīng)用程序獨(dú)占)。也就是說(shuō)服務(wù)器應(yīng)用程序只要監(jiān)聽(tīng)一個(gè)端口就可以收到任意計(jì)算機(jī)的任意端口的數(shù)據(jù)包。
事實(shí)上單臺(tái)PC可以同時(shí)維持的tcp的連接數(shù)是十分巨大的,通過(guò)對(duì)協(xié)議的分析我們會(huì)發(fā)現(xiàn),建立一個(gè)連接也只需要3次握手就完成了如果后面沒(méi)有其他數(shù)據(jù)通信(如心跳什么的業(yè)務(wù)數(shù)據(jù))這個(gè)連接是不會(huì)有什么其他消耗的,所以為了維持連接也僅僅需要儲(chǔ)存遠(yuǎn)程客戶(hù)端地址等少量信息而已,通過(guò)實(shí)際測(cè)試個(gè)人計(jì)算機(jī)的同時(shí)連接數(shù)可以輕松達(dá)到10w的數(shù)量級(jí)(由于單臺(tái)pc客戶(hù)端的數(shù)量有限制,而測(cè)試的pc數(shù)量有限也沒(méi)有繼續(xù)向上測(cè)試,有興趣的朋友可以自己嘗試下)
1 IPAddress ip;
2 TcpListener listener;
3 List mySockets;
4 Thread myListenThread;
5
6
7 private void Form1_Load(object sender, EventArgs e)
8 {
9 ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
10 //ip = IPAddress.Parse("127.0.0.1");
11 listener = new TcpListener(ip, 8500);
12 }
13

14 private void bt_start_Click(object sender, EventArgs e)
15 {
16 try
17 {
18 ip = IPAddress.Parse(tb_ip.Text);
19 listener = new TcpListener(ip, 8500);
20 }
21 catch(Exception ex)
22 {
23 MessageBox.Show(ex.Message);
24 return;
25 }
26 if (myListenThread == null)
27 {
28 myListenThread = new Thread(new ThreadStart(StartGetSocket));

29 myListenThread.IsBackground = true;
30 myListenThread.Start();
31 }
32 else
33 {
34 if(myListenThread.IsAlive)
35 {
36 listener.Stop();
37 myListenThread.Abort();
38 ShowMes("STOP");
39 }
40 else
41 {
42 myListenThread = null;
43 }

44 bt_start_Click(null,null);
45 }
46 }
47
48
49 private void StartGetSocket()
50 {
51 byte[] myBytes=new byte[1024];
52 listener.Start();
53 mySockets = new List();
54 while(true)
55 {
56 while(listener.Pending())
57 {
58 Socket nowSocket = listener.AcceptSocket();

59 ShowMes("成功連接主機(jī):" + nowSocket.RemoteEndPoint.ToString());
60 mySockets.Add(nowSocket);
61 }
62 foreach(Socket tempSocket in mySockets)
63 {
64 while (tempSocket.Available > 0)
65 {
66 tempSocket.Receive(myBytes);
67 ShowMes(tempSocket.RemoteEndPoint.ToString());
68 //ShowMes(byteToHexStr(myBytes));
69 ShowMes(Encoding.Unicode.GetString(myBytes));
70 }
71 }
72 }
73 }

74
75 private void ShowMes(string mes)
76 {
77 if(this.rtb_info.InvokeRequired)
78 {
79 rtb_info.BeginInvoke(new Action((arg1) => rtb_info.AppendText(arg1)), mes+"\r\n");
80 }
81 else
82 {
83 rtb_info.AppendText(mes + "\r\n");
84 }
85 }
復(fù)制
以上是簡(jiǎn)單的服務(wù)端測(cè)試代碼,十分清晰簡(jiǎn)單所以也沒(méi)有寫(xiě)任何注釋。
以上可以看出來(lái)連接的數(shù)量一般是不會(huì)成為瓶頸(注意連接的建立還是需要少量消耗的,當(dāng)然這個(gè)消耗一般存在于網(wǎng)絡(luò)上我們現(xiàn)在暫時(shí)只關(guān)注與對(duì)服務(wù)器本身的消耗),當(dāng)然重要的還是發(fā)的內(nèi)容,一般情況下在網(wǎng)絡(luò)條件允許的情況下,任何個(gè)人計(jì)算機(jī)都可以發(fā)起相當(dāng)?shù)姆?wù)請(qǐng)求。假如數(shù)據(jù)很快通過(guò)網(wǎng)絡(luò)設(shè)備到達(dá)服務(wù)器,這個(gè)時(shí)候服務(wù)器對(duì)這些數(shù)據(jù)的處理能力及方式就顯的至關(guān)重要。打個(gè)比方操作系統(tǒng)但錢(qián)已經(jīng)獲取到1000條針對(duì)當(dāng)前服務(wù)的請(qǐng)求,如果服務(wù)程序依次向操作系統(tǒng)獲取然后處理那后面的請(qǐng)求必然會(huì)阻塞。以前面提供的code為例,即時(shí)單獨(dú)開(kāi)辟一條線(xiàn)程出來(lái)獲取服務(wù)器的數(shù)據(jù),然后再以異步的形式把數(shù)據(jù)委托到UI線(xiàn)程去顯示,再請(qǐng)求過(guò)多(或每秒事物達(dá)到一定量)時(shí),就會(huì)明顯發(fā)現(xiàn)顯示滯后。
服務(wù)器接收到的業(yè)務(wù)數(shù)據(jù)絕不是為了簡(jiǎn)單的顯示,它需要做的事情更多,如何用最小的代價(jià)完成當(dāng)前業(yè)務(wù)成為了制約處理能力(并發(fā)量)的關(guān)鍵(當(dāng)然也許多分布式部署幾臺(tái)服務(wù)器或增加些硬件配置會(huì)有不錯(cuò)的效果)
若是作為測(cè)試人員就必須了解服務(wù)的應(yīng)用場(chǎng)景,實(shí)際業(yè)務(wù),及用戶(hù)的可能行為http高并發(fā)測(cè)試工具,當(dāng)然每次業(yè)務(wù)的每一步服務(wù)器的行為及消耗也應(yīng)該了解,這也是制定高效測(cè)試業(yè)務(wù)流程的基礎(chǔ)。
友情鏈接: 餐飲加盟
地址:北京市海淀區(qū) 電話(huà):010- 郵箱:@126.com
備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有