软件架构

作者在 2009-07-09 22:58:51 发布以下内容
B/S 模式和C/S模式有什么区别?

C/S结构,即Client rver(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境的优势。

B/S结构,即Browser rver(浏览器/服务器)结构,是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种 结构下,用户界面完全通过WWW浏览器实现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现,形成所谓3-tier结构。B/S结构利用不断 成熟和普及的浏览器技术实现原来需要复杂专用软件才能实现的强大功能,并节约了开发成本,是一种全新的软件系统构造技术。这种结构更成为当今应用软件的首 选体系结构,microsoft.net也是在这样一种背景下被提出来的架构,但微软的方案只是一种构想,要成为现实还需要几年,而JAVA技术已经是很 成熟的应用了。

目前大多数应用软件系统都是Client rver形式的两层结构,现在的软件应用系统正在向分布式的Web应用发展;内部的和外部的用户都可以访问 新的和现有的应用系统,Web和Client rver 应用都可以进行同样的业务处理;不同的应用模块共享逻辑组件;通过现有应用系统中的逻辑可以扩展出新的应用系统。这也就是目前应用系统的发展方向。

管理软件的主流技术与管理思想一样,也经历了三个发展时期:界面技术从DOS字符界面,到Windows图形界面(或图形用户界面GUI),直至今天的 Browser浏览器界面。最新浏览器界面,不仅直观和易于使用,更主要的是基于浏览器平台的任何应用软件其界面风格一致,用户对操作培训的要求大为下 降,软件可操作性增强;平台体系结构也从单机单用户发展到文件/服务器(F/S)体系,再到客户机/服务器(C/S)体系和浏览器/服务器(B/S)体 系。

传统的C/S体系结构虽然采用的是开放模式,但这只是系统开发一级的开放性,在特定的应用中无论是Client端还是Server端都还需要特定的软件, 没能提供用户真正期望的开放环境;B/S结构则不同,它的前端是以TCP/IP协议为基础的,企业内的WWW服务器可以接受安装有Web浏览程序的 Internet终端的访问,作为最终用户,只要通过Web浏览器,各种处理任务都可以调用系统资源来完成,这样大大简化了客户端,
基础知识 | 阅读 2418 次
文章评论,共1条
vfdff(作者)
2009-07-19 23:06
1
Visual C++的MFC提供了CSocket类用来实现网络通信。下图给出了CSocket 类的继承关系。<br />
<br />
<br />
  下面介绍VC++在Windows 95中实现Socket的 CSocket 类相关成员函数(这些成员函数实际上是从CAsyncSocket 类继承来的)的使用。<br />
<br />
(1) BOOL Create( UINT nSocketPort = 0, int nSocketType = SOCK_STREAM, long lEvent = FD_READ |FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT| FD_CLOSE,LPCTSTR lpszSocketAddress = NULL )<br />
  该函数用来建立Socket。 其中,nSocketPort 为所选择的Socket 端口,一般要大于 1023,如果该参数为0,则由系统选定一端口,默认值为0 ;nSocketType 为套接字类型:SOCK_STREAM 表示为流套接字,SOCK_DGRAM 表示为数据报套接字,默认值为SOCK_STREAM ;lEvent 标识该Socket 要完成哪种工作,默认值为FD_READ|FD_WRITE|FD_OOB| FD_ACCEPT|FD_CONNECT|FD_CLOSE ;lpszSockAddress 为网络地址信息结构指针,包含网络地址, 默认值为NULL 。<br />
<br />
(2)BOOL Bind( UINT nSocketPort, LPCTSTR lpszSocketAddress = NULL )<br />
  该函数的作用是将Socket 端口与网络地址连接起来。参数含义同上 。<br />
(3)BOOL Listen( int nConnectionBacklog = 5 )<br />
  该函数的作用是等待Socket请求。其中,nConnec-tionBacklog 表示等待队列的长度,默认值为最大值5 。<br />
<br />
(4)virtual BOOL Accept( CAsyncSocket& rConnectedSocket, SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL )<br />
  该函数的作用是取得队列上第一个连接请求并建立一个具有与Socket相同特性的套接字。其中,rConnectedSocket 表示一个新的Socket 。<br />
<br />
(5)BOOL Connect( LPCTSTR lpszHostAddress, UINT nHostPort )<br />
  该函数的作用是提出请求。其中,lpszHostAddress 和 nHostPort 为接受请求进程的网络地址和Socket 端口号。<br />
<br />
(6)virtual void Close( )<br />
  该函数的作用是关闭该Socket 。<br />
<br />
  利用CSocket类直接进行数据通信有两种方式:一种是利用CSocketFile 类和Archive 类去实现,另一种是利用CSocket的成员函数 Receive、Send、ReceiveFrom、SendTo、Listen 和 Accept 等来实现(这些成员函数实际上也是从CAsyncSocket 类继承的)。<br />
  两种方法的实现步骤如下 :<br />
<br />
  Server : Construct-&gt; Creat-&gt; Bind -&gt; Listen-&gt; Accept-&gt; Send-&gt;Close ;<br />
<br />
  Cilent : Construct -&gt;Creat-&gt; Connect-&gt; Receive-&gt; Close。<br />
<br />
   下面就用VC++的代码分别介绍如何运用上述两种方法来实现Socket 编程。<br />
<br />
  1、 利用CSocketFile类和Archive 类实现<br />
<br />
  (1)服务器程序流程<br />
  // 创建一个套接字对象<br />
  CSocket sockSrvr;<br />
<br />
  //为上述套接字对象创建一个套接字<br />
<br />
  sockSrvr.Create(nPort);<br />
<br />
  //开始侦听<br />
  sockSrvr.Listen( );<br />
<br />
  //创建一个新的套接字对象<br />
  CSocket sockRecv;<br />
<br />
  //接受连接<br />
  sockSrvr.Accept( sockRecv );<br />
<br />
// 创建文件对象<br />
CSocketFile file(&amp;sockRecv);<br />
<br />
  //创建一个archive对象<br />
  CArchive arIn(&amp;file, CArchive::load);<br />
<br />
  /*or*/_CArchive arOut(&amp;file, CArchive::store);<br />
<br />
  //使用archive对象传输数据<br />
  arIn &gt;&gt; dwValue;<br />
<br />
  /*or*/ arOut &lt; &lt; dwValue;<br />
<br />
  (2)客户端程序流程<br />
  //创建一个套接字对象<br />
  CSocket sockClient;<br />
<br />
  //为这个对象创建一个套接字<br />
  sockClient.Create( );<br />
<br />
  //寻找一个连接<br />
  sockClient.Connect(strAddr, nPort);<br />
<br />
  //创建一个文件对象<br />
  CSocketFile file(&amp;sockClient);<br />
<br />
  //创建一个archive对象<br />
  CArchive arIn(&amp;file, CArchive::load);<br />
<br />
  /*or*/_CArchive arOut(&amp;file, CArchive::store);<br />
<br />
  //使用这个对象传输数据<br />
  arOut &lt; &lt; dwValue;<br />
<br />
  /*or*/ arIn &gt;&gt; dwValue;<br />
<br />
  上述程序中, nPort 是Socket 的端口号,strAddr 是该机器的IP地址(如202.197.1.3 或 FTP://RedAlert.com等),这两个变量在Server和Client中要一致。当Server进程运行至Listen 后便处于睡眠状态直到Client进程执行Connect 时才被唤醒,而后两个进程便开始传输数据了。<br />
<br />
  2、利用CSocket的成员函数实现<br />
  (1)服务器流程<br />
  //套接字初始化<br />
  if(!AfxSocketInit()){<br />
   MessageBox(&quot;WindowsSocket initial failed!&quot;,&quot;Send&quot;,MB_ICONSTOP);<br />
   Return;<br />
  }<br />
<br />
  // 创建两个套接字对象<br />
  CSocket ChatSend,server;<br />
<br />
  // 创建一个套接字<br />
  if(!ChatSend.Create(nPort)) // nPort=1025<br />
   MessageBox(&quot;SendSocket create failed!&quot;, &quot;Send&quot;,MB_ICONSTOP);<br />
  else{<br />
   // 把本地地址给套接字<br />
ChatSend.Bind(nProt,strAddr);<br />
  // strAddr=&quot;202.196.111.1&quot;<br />
   // 开始侦听<br />
   ChatSend.Listen();<br />
<br />
   // 创建一个新的套接字并和他相连<br />
   ChatSend.Accept(Server);<br />
  }<br />
  //发送一个CString 对象<br />
  Server.SendTo(csSendText,csCounts,nPort,strAddr);<br />
<br />
  // 关闭这两个套接字<br />
  Server.Close();<br />
  ChatSend.Close();<br />
<br />
  (2)客户端程序流程<br />
<br />
  // 套接字初始化<br />
  if(!AfxSocketInit()){<br />
   MessageBox(&quot;WindowsSocket initial failed!&quot;, &quot;Receive&quot;,MB_ICONSTOP);<br />
   return;<br />
  }<br />
<br />
  // 创建一个套接字对象<br />
  CSocket ChatRecieve;<br />
<br />
  // 创建一个套接字<br />
  if(!ChatReceive.Create()){<br />
   MessageBox(&quot;ReceiveSocket create failed!&quot;,&quot;Receive&quot;,MB_ICONSTOP);<br />
   return;<br />
  }<br />
  else{<br />
   // 创建一个对等套接字<br />
   ChatReceive.Connect(strAddr,nPort);<br />
  }<br />
<br />
  //接受一个CString 对象<br />
  ChatReceive.ReceiveFrom(csReceiveText,csCounts,strAddr,nPort);<br />
<br />
  // 关闭套接字<br />
  ChatReceive.Close();<br />
<br />
  上述两个进程完成的工作是:由Server 进程发送一字符串,Client 进程接收。 strAddr 和 nPort 的含义与方法1 中的相同 ;csSendText 和 csReceiveText 为发送与接收的字符串;csCounts为字串长度,这一长度在两个进程中要求接收长度小于或等于发送长度,否则会导致数据传输错误。另外,在程序中要加入头文件afxsock.h, CSocket 类的有关说明均在afxsock.h 中。<br />
<br />
方法1 适合于对多个不同类型数据的通信,方法2 适合于对字符串的通信,具体选用何种方法则取决于具体应用的需求。
游客请输入验证码
浏览1942933次