计算机控制系统-设计报告(ARM)_第1页
计算机控制系统-设计报告(ARM)_第2页
计算机控制系统-设计报告(ARM)_第3页
计算机控制系统-设计报告(ARM)_第4页
计算机控制系统-设计报告(ARM)_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算机控制系统PC-ARM网络通信系统设计报告 姓 名:魏 文学 号:2011132065指导教师:范中磊 完成时间:2011年12月28日0 引言近年来,利用Internet进行网际间通讯,在WWW浏 览、FTP、Gopher这些常规服务,以及在网络电话、多媒体会议等这些对实时性要求严格 的应用中成为研究的热点,而且已经是必需的了。Windows环境下进行通讯程序设计的最基本方法是应用Windows Sockets实现进程间的通讯,为此微软提供了大量基于Windows Sockets的通讯API,如WinSockAPI、WinInetAPI和ISAPI,并一直致力于开发更快、 更容易的通讯API,将其和MFC集成在一起以使通讯编程越来越容易。文中重点介绍了使用MFC的CSocket类编写PC端网络通讯程序的设计方法,并基于Windows CE开发环境利用VS2005设计ARM端网络通讯程序。1 设计思路MFC把复杂的WinSock API函数封装到类里,这使得编写网络应用程序更容易。CAsyncSocket类逐个封装了WinSock API,为高级网络程序员 提供了更加有力而灵活的方法。这个类基于程序员了解网络通讯的假设,目的是为了在MFC中使用WinSock,程序员有责任处理诸如阻塞、字节顺序和在Unicode与MBCS 间转换字符的任务。为了给程序员提供更方便的接口以自动处理这些任务,MFC给出 了CSocket类,这个类是由CAsyncSocket类继承下来的,它提供了比CAsyncSocket更高层的WinSock API接口。Csocket类和CsocketFile类可以与Carchive类一起合作来管理发送和接收的数据,这使管理数据收发更加便利。CSocket对象提供阻塞模式,这对于Carchive的同步操作是至关重要的。阻塞函数(如Receive()、Send()、ReceiveFrom()、SendTo() 和Accept())直到操作完成后才返回控制权,因此如果需要低层控制和高效率,就使用CasyncSock类;如果需要方便,则可使用Csocket类。 一些网络应用程序(如网络电话、多媒体会议工具)对实时性要求非常强,要求能够直接应用WinSock发送和接收数据。为了充分利用MFC 的优势,首选方案应当是MFC中的CAsyncSocket类或CSocket类,这两个类完全封装了WinSock API,并提供更多的便利。本实例介绍应用这两个类的编程模型,并引出相关的成员函数与一些概念的解释。 CSocket类是由CAsyncSocket继承而来的,事实上,在MFC中CAsyncSocket 逐个封装了WinSock API,每个CAsyncSocket对象代表一个Windows Socket对象,使用CAsyncSocket 类要求程序员对网络编程较为熟悉。相比起来,CSocket类是CAsyncSocket的派生类, 继承了它封装的WinSock API。一个CSocket对象代表了一个比CAsyncSocket对象更高层次的Windows Socket的抽象,CSocket类与CSocketFile类和CArchive类一起工作来发送和接收数据,因此使用它更加容易使用。CSocket对象提供阻塞模式,因为阻塞功 能对于CArchive的同步操作是至关重要的。在这里有必要对阻塞的概念作一解释: 一个socket可以处于阻塞模式或非阻塞模式,当一个套接字处于阻塞模式(即同步操作)时,它的阻塞函数直到操作完成才会返回控制权,之所以称为阻塞是因为此套接字的阻塞函数在完成操作返回之前什么也不能做。如果一个socket处于非阻塞模式(即异步操作),则会被调用函数立即返回。在CAsyncSocket类中可以用GetLastError 成员函数查询最后的错误,如果错误是WSAEWOULDBLOCK则说明有阻塞,而CSocket绝不会返回WSAEWOULDBLOCK,因为它自己管理阻塞。微软建议尽量使用非阻塞模式,通过网络事件的发生而通知应用程序进行相应的处理。但在CSocket类中,为了利用CArchive 处理通讯中的许多问题和简化编程,它的一些成员函数总是具有阻塞性质的,这是因为CArchive类需要同步的操作。在Win32环境下,如果要使用具有阻塞性质的套接字,应该放在独立的工作线程中处理,利用多线程的方法使阻塞不至于干扰其他线程,也不会把CPU时间浪费在阻塞上。多线程的方法既可以使程序员享受CSocket带 来的简化编程的便利,也不会影响用户界面对用户的反应。 1.1 CAsyncSocket类编程模型在一个MFC应用程序中,要想轻松处理多个网 络协议,而又不牺牲灵活性时,可以考虑使用CAsyncSocket类,它的效率比CSocket 类要高。CAsyncSocket类针对字节流型套接字的编程模型简述如下:(1)构造一个CAsyncSocket对象,并用这个 对象的Create成员函数产生一个Socket句柄。可以按如下两种方法构造: CAsyncSocket sock; /使用默认参数产生一个字节流套接字Sock.Create(); 或在指定端口号产生一个数据报套接字CAsyncSocket*pSocket=newCAsyncSocket;intnPort=27;pSocket-Create(nPort,SOCK-DGRAM); 第一种方法在栈上产生一个CAsyncSocket对象,而第二种方法在堆上产生CAsyncSocket对象;第一种方法中Create()成员函数用缺省参数产生一个字节流套接字,第二种方法中用Create()成员函数在指定的端口产生一个数字报套接字。Create()函数的原型为:BOOL Create( UINT nSocketPort = 0, int nSocketType = SOCK_STREAM,LPCTSTR lpszSocketAddress = NULL ); 该函数的参数有:1)端口,UINT类型。注意:如果是服务方,则使 用一个众所周知的端口供服务方连接;如果是客户方,典型做法是接受默认参数,使 套接字可以自主选择一个可用端口;2)socket 类型,可以是SOCK-STREAM(默认值,字节流)或SOCK-DGRAM(数据报);3)socket的地址,例如3。 (2)如是客户方程序,用CAsyncSocketConnect()成员函数连接到服务方;如是服务方程序,用CAsyncSocketListen()成员函数开始监听,一旦收到连接请求,则调用CAsyncSocketAccept()成员函数开始接收。注意:CAsyncSocket Accept()成员函数要用一个新的并且是空的CAsyncSocket对象作为它的参数,这里所说 的空的指的是这个新对象还没有调用Create()成员函数。 (3)调用其他的CAsyncSocket类的Receive()、ReceiveFrom()、Send()和SendTo()等成员函数进行数据通信。 (4)通讯结束后,销毁CAsyncSocket对象。如果是在栈上产生的CAsyncSocket对象,则对象超出定义的范围时自动被析构;如果是在堆上产生,也就是用了new这个操作符,则必须使用delete操作符销毁CAsyncSocket 对象。 1.2 CSocket类编程模型 使用CSocket对象涉及CArchive和CSocketFile 类对象。以下介绍的针对字节流型套接字的操作步骤中,只有第3步对于客户方和服务方操作是不同的,其他步骤都相同。 (1)构造一个CSocket对象。 (2)使用这个对象的Create()成员函数产生一个socket对象。在客户方程序中,除非需要数据报套接字,Create()函数一般情况下应该使用默认参数。而对于服务方程序,必须在调用Create时指定一个端口。需要注意的是,Carchive类对象不能与数据报(UDP)套接字一起工作,因此对于数据报套接字,CAsyncSocket和CSocket 的使用方法是一样的。 (3)如果是客户方套接字,则调用CAsyncSocket Connect()函数与服务方套接字连接;如果是服务方套接字,则调用CAsyncSocketListen()开始监听来自客户方的连接请求,收到连接请求后,调用CAsyncSocketAccept()函数接受请求,建立连接。请注意Accept()成员函数需要一个新的并且为空的CSocket对象作为它的参数,解释同上。 (4)产生一个CSocketFile对象,并把它与CSocket 对象关联起来。(5)为接收和发送数据各产生一个CArchive 对象,把它们与CSocketFile对象关联起来。切记CArchive是不能和数据报套接字一起工作的。 (6)使用CArchive对象的Read()、Write()等函数在客户与服务方传送数据。(7)通讯完毕后,销毁CArchive、CSocketFile和CSocket对象。2 PC端通讯程序设计(1)启动Visual Studio 2010,创建一个基于对话框架的MFC应用程序项目,将该项目命名为Test;在MFC向导中选中Windows 套接字;(2)在对话框中按照实际需要添加控件,添加控件如表2-1;表2-1控件类型控件IDCaption属性控件变量变量类型按钮IDC_CONNECTBUTTON连接-按钮IDC_DISCONNECTBUTTON断开-按钮IDC_SENDBUTTON发送-按钮IDC_SENDCLEARBUTTON清除发送-按钮IDC_RECEIVECLEARBUTTON删除-按钮IDCANCEL退出程序-编辑框IDC_IPADDRESS无m_IPAddressCString编辑框IDC_PORT无m_PortUINT编辑框IDC_OUTPUTEDIT无m_OutputCString编辑框IDC_CONNECTEDIT无m_ConnectCString列表框IDC_INPUTEDIT无m_IutputCListBox单选按钮IDC_SERVERRADIO服务器m_Statusint单选按钮IDC_CLIENTRADIO客户端-编辑框控件IDC_CONNECTEDIT属性“Read Only”值为“True”;IDC_SERVERRADIO属性“Group”值为“True”。(3)使用Class Wizard为应用程序的按钮添加鼠标单击消息响应函数;/*连接按钮消息处理函数*/void CTestDlg:OnConnect() / TODO: Add your control notification handler code hereCString msg;UpdateData(TRUE); if (m_Status=0 ) /serverif ( m_ServerSocket!=NULL) m_Connect=请断开连接!;UpdateData(FALSE);elsem_Connect=等待连接.;UpdateData(FALSE);if(!AfxSocketInit() MessageBox(_T(WindowsSocket初始化失败!),_T(发送),MB_ICONSTOP); return; m_ServerSocket=new CNewSocket;m_ServerSocket-m_Status=m_Status;m_ServerSocket-GetDlg(this); if(!m_ServerSocket-Create(m_Port) MessageBox(_T(SendSocket创建失败!), _T(发送),MB_ICONSTOP); else m_ServerSocket-Listen(); else if (m_Status=1) /Clientif (m_ClientSocket!=NULL) m_Connect=请断开连接!;UpdateData(FALSE);elsem_Connect=连接服务器.;UpdateData(FALSE);if(!AfxSocketInit()MessageBox(_T(WindowsSocket初始化失败!), _T(接收),MB_ICONSTOP); return; m_ClientSocket=new CNewSocket; m_ClientSocket-GetDlg(this); m_ClientSocket-m_Status=m_Status;if(!m_ClientSocket-Create() MessageBox(_T(ReceiveSocket创建失败!),_T(接收),MB_ICONSTOP); return; else if (!m_ClientSocket-Connect(m_IPAddress,m_Port)CString str=m_Connect;SocketReset();m_Connect=str;m_Connect+=失败!;UpdateData(FALSE);else m_Connect+=完成!;m_file=new CSocketFile(m_ClientSocket); m_arIn=new CArchive(m_file, CArchive:load); m_arOut=new CArchive(m_file, CArchive:store); UpdateData(FALSE); if (m_Status=-1) msg=请选择模式!;AfxMessageBox(msg);/*断开按钮消息处理函数*/void CTestDlg:OnDisconnect()/ TODO: Add your control notification handler code hereif (m_arOut!=NULL)SocketReset();m_Connect=已断开!;UpdateData(FALSE);/*发送按钮消息处理函数*/void CTestDlg:OnSend()/ TODO: Add your control notification handler code hereif (m_arOut)if (m_Status=0)UpdateData(TRUE);*m_arOutFlush(); else UpdateData(TRUE);*m_arOutFlush(); else AfxMessageBox(_T(无有效连接!);/*清除按钮消息处理函数*/void CTestDlg:OnSendclear()/ TODO: Add your control notification handler code herem_Output=;UpdateData(FALSE);/*删除按钮消息处理函数*/void CTestDlg:OnReceiveclear()/ TODO: Add your control notification handler code herem_Input.DeleteString(m_Input.GetCurSel(); UpdateData(FALSE);/*服务器单选按钮消息处理函数*/void CTestDlg:OnServerradio()/ TODO: Add your control notification handler code hereUpdateData(TRUE);GetDlgItem(IDC_IPADDRESS)-EnableWindow(FALSE);GetDlgItem(IDC_PORT)-EnableWindow(TRUE);UpdateData(FALSE);/*客户端单选按钮消息处理函数*/void CTestDlg:OnClientradio()/ TODO: Add your control notification handler code hereUpdateData(TRUE);GetDlgItem(IDC_IPADDRESS)-EnableWindow(TRUE);GetDlgItem(IDC_PORT)-EnableWindow(TRUE);UpdateData(FALSE);(4)使用Class Wizard在应用程序中定义新类CNewSocket,其基类选择为CSocket;重载NewSocket类的OnAccept()、OnReceive()、OnClose()函数;增加公有变量CTestDlg *m_dlg; int m_Status并添加一成员函数void GetDlg(CTestDlg *dlg);void CNewSocket:OnAccept(int nErrorCode)/ TODO: 在此添加专用代码和/或调用基类if (m_dlg-m_ClientSocket=NULL) m_dlg-OnAccept();CSocket:OnAccept(nErrorCode);void CNewSocket:OnReceive(int nErrorCode)/ TODO: 在此添加专用代码和/或调用基类m_dlg-OnReceive();CSocket:OnReceive(nErrorCode);void CNewSocket:GetDlg(CTestDlg *dlg)m_dlg=dlg;void CNewSocket:OnClose(int nErrorCode)/ TODO: 在此添加专用代码和/或调用基类m_dlg-OnClose();CSocket:OnClose(nErrorCode);(5)为窗口类TestDlg添加5个公有成员变量:CSocketFile *m_file;CArchive *m_arOut;CArchive *m_arIn;CNewSocket* m_ServerSocket;CNewSocket* m_ClientSocket;并添加公有4个成员函数:void SocketReset();void OnClose();void OnReceive();void OnAccept();编写公有函数代码:void CTestDlg:SocketReset()if (m_arIn!=NULL) delete m_arIn;m_arIn=NULL;if (m_arOut!=NULL) delete m_arOut;m_arOut=NULL;if (m_file!=NULL) delete m_file;m_file=NULL;if (m_ClientSocket!=NULL)delete m_ClientSocket;m_ClientSocket=NULL;if (m_ServerSocket!=NULL) delete m_ServerSocket;m_ServerSocket=NULL;m_Connect=;UpdateData(FALSE);void CTestDlg:OnClose()if (m_ClientSocket-m_Status=0) m_Connect=客户端;else m_Connect=服务器;m_Connect+=已断开!; UpdateData(FALSE);void CTestDlg:OnReceive()CString str1,str2;*m_arInstr2;str1=_T(PC机:);str1+=str2;m_Input.AddString(str1); m_Input.SetCurSel(m_Input.GetCount ()-1);UpdateData(FALSE);void CTestDlg:OnAccept()/u_long iMode = 1; m_Connect+=完成!;UpdateData(FALSE);m_ClientSocket=new CNewSocket;/m_ClientSocket-IOCtl(FIONBIO,&iMode);m_ClientSocket-GetDlg(this);m_ServerSocket-Accept(*m_ClientSocket);m_ClientSo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论