动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 软件工程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ 软件工程 ]的信息

本月文章推荐
.探究需求管理的本质.
..NET Remoting构建分布式数据库查.
.UML在商业活动建模中的应用.
.构建下一代软件架构SOA.
.Z5NTS功能之netstat(网络工具).
.软件开发质量管理层次模型(1).
.Windows 工作流活动技术概览.
.利用GDI+的双缓冲技术来提高绘图.
.对软件项目管理的探讨.
.统一建模语言UML轻松入门之用例.
.软件项目需求分析的文档包括的内.
..NET Remoting程序开发入门篇.
.细说ADO.NET命令.
.黑盒测试和白盒测试.
..NET对IT专业人员的重要意义.
..NET下基于组件的分布式系统动态.
.IBM的MARS加密算法实现(2).
.IT项目管理向沟通要效率.
.Rational统一过程(1).
.项目需求变更得不到有效控制所带.

基于.NET的多用户客户端设计

发表日期:2008-3-23 |




  摘要: 在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。输入服务器的IP地址和端口号。

  2.4添加"用户登陆"响应函数,输入用户名和连接数,系统根据用户输入的想要建立的连接数,自动生产连接并将其放入链表中。

  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];
::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 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. 结束语

  经过实际验证,该程序能够很好的测试服务器的连接承受能力,从理论上来说,用户可以指定任意多的连接,实际上,连接数受到计算机资源的限制。 在通信过程中,各个连接能够良好的进行,不会互相干扰。  进入讨论组讨论。

上一篇:客户关系管理的三大纪律 人气:244
下一篇:用.Net Framework设计检查EMail程序 人气:297
浏览全部软件工程的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-8-21 Nucleus v3.33 多国语言版
2008-8-21 HDWiki v4.0 bulid 080821 UTF-8
2008-8-21 明科在线客服系统 v6.0
2008-8-21 KesionCMS v5.0.2 正式版 utf-8
2008-8-21 KesionEshop v5.0.2 正式版 utf-8
2008-8-21 HDWiki v4.0 bulid 080821 GBK
2008-8-21 新文互动酷站展示系统 v1.5
2008-8-21 Punbb v1.2.20 多国语言版
2008-8-21 QQ头像网 beta
2008-8-16 iLaba Player(小喇叭播放器) v2.
2008-8-16 DoubleClickFix 鼠标双击修正工具
2008-8-16 CrystalCPUID 4.15.2.451
2008-8-16 VeryCD 电驴(easyMule) 1.0.4 Bu
2008-8-16 uTorrent 1.8 Build 11813 - Sta
2008-8-16 比特精灵(BitSpirit) v3.3.2.287
2008-8-16 StayInTune音叉 v1.0 破解版
2008-8-16 iChing《周易》汉化补丁 v1.0
2008-8-16 Starmap星空图v1.0汉化破解版
  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号