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

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

基于.NET的多用戶客戶端設計

2019-11-17 04:39:47
字體:
來源:轉載
供稿:網友


  摘要: 在C/S 模式中,服務器端往往是設計的重點。為了測試服務器的性能,不得不使用大量的計算機作為客戶端。在實際情況中,往往無法提供大量的計算機用以測試,同時,這也是資源的浪費,為了解決這個問題,本文提出了模擬多用戶客戶端的設計方法,并給出具體代碼說明。


  要害字:多用戶 客戶端 連接隊列

  1. 概述

  在C/S 模式中,服務器端往往是設計的重點。一般來說,服務器的能夠承受的連接數量是衡量一個服務器性能好壞的重要標準,為了測試服務器能夠承受的連接數,我們必須使用多臺客戶機來測試他的性能.可是,很多情況下,我們沒有那么多的機器,同時使用多臺機器進行測試也是浪費資源,為此,我們設計了模擬多用戶客戶端程序來解決這個問題。

  本文采用MFC的CSocket類在.NET平臺上進行設計.所謂的模擬多用戶就是用一個客戶端程序來建立多個與服務器的連接,就似乎多個客戶端與服務器進行連接一樣。設計的重點是:

   程序能夠生成用戶指定的數目的連接;

   用戶可以在建立的連接中任意指定某個連接進行通信;

   用戶可以隨意更換連接進行通信測試,每個連接不會互相混淆,尤其是在讀寫數據的時候,不能張冠李戴;

   用戶可以隨意指定斷開某個連接,而不會影響其他連接。

  那么這么多的連接究竟如何治理呢?

  首先,我們要有一種數據結構來描述每個連接的具體情況。本文采用了結構體。

  自定義結構體strUCt socket_info
{ CSocket* s_client; //保存用戶的SOCKET值
u_long client_addr; //保存用戶網絡地址
CString username; //用戶昵稱
int id; //連接號
} ;  然后,使用C++的模板類CList來治理這些連接。以后所做的所有事情就是對這個鏈表的操作。

  2.設計步驟:

  2.1創建一個基于對話框的工程CClientDlg.在MFC應用程序向導中選中windows 套接字。

  2.2給對話框添加菜單,并添加菜單項,包括配置服務器、用戶登陸、退出、通信、斷開連接。

  2.3添加"配置服務器"響應函數OnServerConfserver(),調出服務器配置對話框Server Configure。輸入服務器的
  2.5 添加"通信"響應函數OnCommunication(),調出通信對話框,如圖1所示。點擊"發送",發送數據;點擊"接收",接收數據;點擊"斷開該連接",關閉socket,并從鏈表中刪除該連接。

  2.6 添加"退出"菜單響應函數。遍歷整個連接隊列,將所有的連接斷開并刪除隊列中所有結構體,將隊列清空。

進入討論組討論。
  3.具體代碼:

  3.1 聲明全局變量
struct socket_info {……} ; //如前所示
extern CList<socket_info,socket_info&> s_info; //鏈表類
extern CClientSocket* lSocket; //用于標識當前正在通信的連接
extern int id; //用于指示用戶選擇的要進行通信的連接
extern char pBuf[100]; //接收緩沖區  3.2 實現CClientDlg.cpp中的響應函數:
void CClientDlg::OnServerConflogin()//"用戶登陸"菜單響應函數
{ CLoginDlg dlg;
int t=0; //記錄失敗的連接數
int size=s_info.GetSize(); //查看當前連接鏈表的長度
if(dlg.DoModal()==IDOK)
{ socket_info* pInfo; //聲明結構體
for(int i=0;i<dlg.m_nUserCount;i++)
{ pInfo = new socket_info;
pInfo->s_client=new CClientSocket();
if(!(pInfo->s_client->Create())) //創建socket

{ delete pInfo->s_client;
pInfo->s_client=NULL;
}
if(!(pInfo->s_client->Connect(m_strIpaddress,m_Port))) //連接
{ t++; //假如失敗,t增加,釋放空間
delete pInfo->s_client;
pInfo->s_client=NULL;
}
else{ //假如成功
pInfo->id =size+i; //設置當前連接的id
pInfo->username=dlg.m_strUsername;
s_info.AddTail(*pInfo); //將成功的連接加入鏈表
}
}
int c=dlg.m_nUserCount-t; //得到成功的連接數
char message[10];
::s
strcat(message,"個連接成功");
if(c>=0) AfxMessageBox(message); //彈出提示對話框
}
}  3.3 實現CommunicationDlg.cpp中的響應函數:
void CCommunicationDlg::OnBnClickedQuery()//"發送"按鈕的響應函數
{ lSocket=NULL;
UpdateData();
id=atoi(m_strQueryId); //獲得用戶輸入的連接號
POSITION pos;
if(!s_info.IsEmpty())
{ socket_info info=s_info.GetHead();
if(id>=s_info.GetCount()) //可選擇的id必須小于鏈表的大小
MessageBox("the data is larger than the count of the list","Alert",MB_OK);
else{ for(pos=s_info.GetHeadPosition();;) //遍歷整個鏈表
{ if(info.id==id&&!info.s_client==NULL)
{ lSocket=info.s_client; //將用戶指定的連接的socket賦予lSocket lSocket->Send(m_strSendData,m_strSendData.GetLength());
//發送m_strSendData文本框中的文本
break; }
if(pos==NULL) break;
else info =s_info.GetNext(pos);
}
}
}else AfxMessageBox("the queer is empty!"); //鏈表為空
}void CCommunicationDlg::OnBnClickedAdd() //"接收"按鈕的響應函數
{ UpdateData();
BOOL MsgEnd=TRUE;
int iRecv; //每次讀取的字符數
if(!lSocket==NULL)
{ memset(pBuf,0,100); //清空緩沖區
do{ iRecv=lSocket->Receive(pBuf,100);//接收數據
if(iRecv<100&&iRecv>0) { MsgEnd=TRUE;}
pBuf[iRecv]=0; //給緩沖區結尾,即賦'/0'
}while(!MsgEnd);
m_ReceData.SetSel(0,-1);
m_ReceData.ReplaceSel(pBuf); //在m_ReceData文本框中顯示接收的字符
} else AfxMessageBox("the socket was disconnected");
}void CCommunicationDlg::OnBnClickedCancel()//"斷開該連接"按鈕的響應函數  與"退出"菜單響應函數類似,不同之處在于,退出菜單要清空整個隊列,而"斷開該連接"函數僅僅是找到當前的正在通信的連接并將其斷開。
……
socket_info info=s_info.GetAt(s_info.FindIndex(id)); //找到id對應的結構體
if(!info.s_client==NULL){
if(info.s_client->ShutDown(2)){ //斷開該連接
info.s_client->Close();
delete info.s_client;
info.s_client=NULL;
s_info.RemoveAt(s_info.FindIndex(id)); //從鏈表中刪除該結構體
AfxMessageBox("Disconnect successfully!");   4. 設計技巧

  在設計中,我們要注重幾個問題,這些問題的解決直接影響到程序的性能。

  4.1 對于一個基于對話框的應用程序,Visual MFC應用程序向導不會給對話框創建菜單。假如要在對話框中顯示菜單,必須把它作為一個資源,并連接到對話框窗口。具體步驟:

   右擊資源試圖的"菜單"選項,創建一個菜單IDR_MENU1,添加菜單項;

   打開資源試圖的"對話框"選項,右擊對話框(IDD_CLIENT_DIALOG),選擇"屬性", 在彈出的屬性表中找到"Menu",將它的值設為IDR_MENU1;
  4.2 用戶要建立連接,就要指定連接數,問題是,用戶不一定一次指定所有的連接。比如說,第一次,用戶指定了50個連接,程序將50個連接加入到連接隊列中。經過測試,用戶發現50個連接運行情況良好,于是,用戶想要測試100個連接的運行情況,這時,我們不能要求用戶退出并重新運行程序,然后指定100個連接重新進行測試。我們要做的就是讓用戶能夠再次指定50個連接,并且將這50個連接加入到前50個連接的后面。所以,在設計時,每次建立指定數目的連接前,必須查詢隊列的長度,然后將建立的連接加入到隊列中正確的位置上。正如"用戶登陸"菜單響應函數所示:
int size=s_info.GetSize();//查看當前連接鏈表的長度

pInfo->id =size+i; //設置當前連接的id  4.3 每次用戶指定某個連接進行測試時,程序都要自動搜索連接隊列找到指定的連接,并發送信息。問題是,我們的發送和接收是不同的響應函數,如何保證接收信息的連接是用戶指定的連接呢?例如,用戶建立了100個連接,指定Id為59的連接進行通信,當發送數據時,程序自動找到Id=59的socket發送數據,可是,當接收數據時,程序怎么知道是哪個連接負責接收數據呢?我們可以在接收響應函數中再次查找隊列,但是,這樣不但增加了系統資源的消耗,而且增加了系統的延遲。我們采用全局變量lSocket來解決這個問題。
lSocket=info.s_client;//將用戶指定的連接的socket賦予lSocket
lSocket->Send(m_strSendData,m_strSendData.GetLength());//發文本框中的文本
iRecv=lSocket->Receive(pBuf,100);   4.4 每次用戶退出程序之前,必須斷開所有連接,并清空隊列。 如"退出"菜單響應函數所示。

  5. 結束語

  經過實際驗證,該程序能夠很好的測試服務器的連接承受能力,從理論上來說,用戶可以指定任意多的連接,實際上,連接數受到計算機資源的限制。 在通信過程中,各個連接能夠良好的進行,不會互相干擾。 進入討論組討論。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
视频在线观看一区二区| 色综合视频一区中文字幕| 欧美成人免费小视频| 国产69精品99久久久久久宅男| 97国产精品视频| 久久亚洲精品国产亚洲老地址| 亚洲福利小视频| 国内精品久久久久影院优| 日韩美女av在线免费观看| 高清日韩电视剧大全免费播放在线观看| 中文字幕在线看视频国产欧美| 日韩精品一区二区三区第95| 欧美另类高清videos| 国产精品678| 97婷婷大伊香蕉精品视频| 最近2019中文字幕第三页视频| 欧美洲成人男女午夜视频| 91九色单男在线观看| 亚洲精品美女视频| 日本三级久久久| 亚洲第一网站免费视频| 国产成人精品在线观看| 都市激情亚洲色图| 日韩国产一区三区| 精品亚洲va在线va天堂资源站| 久久精品亚洲一区| 91久久久久久国产精品| 欧美日韩综合视频网址| 中文字幕av一区| 国产精品一区二区三| 亚洲精品国产精品国自产观看浪潮| 国产在线视频欧美| 欧美一级在线亚洲天堂| 欧美日韩一二三四五区| 日本精品久久电影| 国产国语刺激对白av不卡| 欧美日韩国产丝袜另类| 亚洲精品www久久久久久广东| 日韩国产高清污视频在线观看| 国产午夜精品一区理论片飘花| 精品国产乱码久久久久久虫虫漫画| 亚洲r级在线观看| 亚洲精品99久久久久| 日韩女优人人人人射在线视频| 日韩欧美视频一区二区三区| 久久成年人视频| 亚洲欧美在线播放| 色噜噜狠狠色综合网图区| 中文字幕视频一区二区在线有码| 一区二区三区视频在线| 国产精品爽爽爽| 久久精品男人天堂| 欧美另类在线观看| 亚洲一区二区久久| 久久久久久久久91| 国产精品专区第二| 51久久精品夜色国产麻豆| 久久久久久com| 日韩经典中文字幕| 欧美成人中文字幕在线| 欲色天天网综合久久| 成人网在线观看| 8090成年在线看片午夜| 亚洲午夜女主播在线直播| 91久久久久久久久久久| 色播久久人人爽人人爽人人片视av| 8090理伦午夜在线电影| 亚洲精品99久久久久| 亚洲国产精品高清久久久| 午夜免费久久久久| 亚洲第一福利网| 狠狠躁夜夜躁久久躁别揉| 亚洲深夜福利视频| 伊人精品在线观看| 国产精品偷伦免费视频观看的| 欧美性生活大片免费观看网址| 欧美刺激性大交免费视频| 亚洲一区二区三区成人在线视频精品| 青青草成人在线| 亚洲电影第1页| 97视频在线观看成人| 色婷婷综合成人av| 中文字幕自拍vr一区二区三区| 国产裸体写真av一区二区| 亚洲国产欧美一区二区丝袜黑人| 国产有码一区二区| www.日韩免费| 中文字幕亚洲一区| 国产成人啪精品视频免费网| 欧美另类精品xxxx孕妇| 中文字幕日韩精品有码视频| 中文字幕日韩精品在线| 黄色精品一区二区| 亚洲免费伊人电影在线观看av| 国产成人高清激情视频在线观看| 中文字幕欧美日韩精品| 亚洲天堂男人天堂| 亚洲bt天天射| 精品美女永久免费视频| 色先锋久久影院av| 国产精品视频99| 亚洲影影院av| 日韩高清电影免费观看完整| 亚洲第一网中文字幕| 最近更新的2019中文字幕| 欧美成人精品在线播放| 国产精品无av码在线观看| 亚洲精品日韩av| 欧美黑人极品猛少妇色xxxxx| 韩剧1988在线观看免费完整版| 欧美激情精品久久久久久黑人| 91免费综合在线| 欧美日韩亚洲系列| 欧美综合国产精品久久丁香| 国内精品国产三级国产在线专| 精品视频在线导航| 色播久久人人爽人人爽人人片视av| 美日韩丰满少妇在线观看| 三级精品视频久久久久| 欧洲成人在线观看| 亚洲最大的av网站| 日韩成人av在线播放| 国产自产女人91一区在线观看| 2019av中文字幕| 国产成人精品国内自产拍免费看| 色悠悠久久久久| 亚洲欧美激情另类校园| 国产有码在线一区二区视频| 国产在线观看精品| 欧美日韩国产二区| 精品亚洲一区二区| 久久天天躁夜夜躁狠狠躁2022| 国产精品视频公开费视频| 激情懂色av一区av二区av| 欧美猛交ⅹxxx乱大交视频| 亚洲第一av网站| 精品一区二区亚洲| 久久精品电影网| 久久99精品国产99久久6尤物| 国产精品一区二区久久国产| 亚洲国产一区二区三区四区| 欧美激情乱人伦| 亚洲成人精品视频在线观看| 91色中文字幕| 在线国产精品视频| 欧美精品国产精品日韩精品| 欧美精品激情视频| 欧美电影免费观看高清| 97久久国产精品| 久久久久久久久久久久久久久久久久av| 欧美精品videosex性欧美| 国产999在线观看| 日本精品免费一区二区三区| 亚洲肉体裸体xxxx137| 久久资源免费视频| 亚洲精品mp4| 国产免费一区二区三区在线能观看| 在线看片第一页欧美| 精品国产拍在线观看| 欧美成人免费一级人片100| 亚洲老板91色精品久久| 欧美诱惑福利视频| 久久久久久91| 国产精品久久久久久久久久久久久|