淺談基于.NET的多用戶客戶端設計[2]

發表于:2007-05-14來源:作者:點擊數: 標簽:設計多用戶.NET客戶端淺談
3.具體代碼: 3.1聲明全局變量 struct socket_info {……} ; //如前所示 extern CList s_info; //鏈表類 extern CC lientSocket* lSocket; //用于標識當前正在通信的連接 extern int id; //用于指示用戶選擇的要進行通信的連接 extern char pBuf[100]; //接收

  3.具體代碼:

  3.1聲明全局變量

  struct socket_info {……} ; //如前所示

  extern CList 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

  { 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];

  ::sprintf(message,"%d",c); //將數字轉換成字符串

  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 suclearcase/" target="_blank" >ccessfully!");

  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.結束語

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

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97