基于tcpip 的多线程通信及其在远程监控系统中的应用

上传人:xzh****18 文档编号:35446578 上传时间:2018-03-15 格式:DOCX 页数:5 大小:83.08KB
返回 下载 相关 举报
基于tcpip 的多线程通信及其在远程监控系统中的应用_第1页
第1页 / 共5页
基于tcpip 的多线程通信及其在远程监控系统中的应用_第2页
第2页 / 共5页
基于tcpip 的多线程通信及其在远程监控系统中的应用_第3页
第3页 / 共5页
基于tcpip 的多线程通信及其在远程监控系统中的应用_第4页
第4页 / 共5页
基于tcpip 的多线程通信及其在远程监控系统中的应用_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

《基于tcpip 的多线程通信及其在远程监控系统中的应用》由会员分享,可在线阅读,更多相关《基于tcpip 的多线程通信及其在远程监控系统中的应用(5页珍藏版)》请在金锄头文库上搜索。

1、基于TCP/IP 的多线程通信及其在远程监控系统中的应用作者:上海交通大学自动化研究所(200030)王金廉谢剑英 贾 青来源:电子技术应用摘 要: 提出了一种在Windows NT 下基于TCP/IP 协议的多线程通信的设计与实现方法,在此基础上给出了多线程通信在蓄电池远程监控系统中的应用实例。关键词: 多线程 实时性 TCP/IP 协议远程监控系统传统的应用程序都是单线程的,即在程序运行期间,由单个线程独占CPU 的控制权,负责执行所有任务。在这种情况下,程序在执行一些比较费时的任务时,就无法及时响应用户的操作,影响了应用程序的实时性能。在监控系统,特别是远程监控系统中,应用程序往往不但要

2、及时把监控对象的最新信息反馈给监视客户(通过图形显示),还要处理本地机与远程机之间的通信以及对控制对象的实时控制等任务,这时,仅仅由单个线程来完成所有任务,显然无法满足监控系统的实时性要求。在DOS 系统下,这些工作可以由中断来完成。而在Windows NT 下,中断机制对用户是不透明的。为此,可引进多线程机制,主线程专门负责消息的响应,使程序能够响应命令和其他事件。辅助线程可以用于完成其他比较费时的工作,如通信、图形显示和后台打印等,这样就不至于影响主线程的运行。 Windows NT 多线程概述Windows NT 是一个真正的抢占式多任务操作系统。在 Windows NT 中,启动一个应

3、用程序就是启动该应用程序的一个实例,即进程。进程由一个或多个线程构成,拥有内存和资源,但自己不能执行自己,而是进程中的线程被调度执行。进程至少要有一个线程,当创建一个进程时,就创建了一个线程,即主线程。主线程可以创建其他辅助线程,由主线程创建的线程又可创建线程。每个线程都可指定优先级,操作系统根据线程的优先级调度线程的执行。Windows NT 中使用多线程的方法有三种: 使用C 多线程库函数; 使用CreateThread() 等Win32 函数; 使用MFC 类。本文采用第三种方法。在Visual C+5.0 中,MFC 应用程序用CWinThread 对象表示线程。基本操作如下: 创建新

4、线程:调用MFC 全局函数AfxBeginThread ()创建新线程。AfxBeginThread()启动新线程并返回控制,然后,新线程和调用AfxBeginThread()的线程同时运行。它的返回值为指向CWinThread 对象的指针; 暂停恢复线程:调用CWinThread 类成员函数SuspendThread()暂停线程的运行,调用ResumeThread()成员函数恢复线程的运行; 终止线程:在线程内部可调用全局函数AfxBeginThread()终止线程的运行,否则,线程执行结束后,线程自动从线程函数返回并释放线程占有的资源。 基于 TCP/IP 的多线程编程TCP/IP 是ln

5、ternet 上广泛使用的一种协议,可用于异种机之间的互联。TCP/IP 协议本身是非常复杂的,然而在网络编程中,程序员不必考虑TCP/IP 的实现细节,只需利用协议的网络编程接口Socket(亦称套接字)即可。在 Windows 中,网络编程接口是 Windows Socket 它包含标准的Berkley Sockets 的功能调用的集合,以及为 Windows 所做的一些扩展。TCP/IP 协议的应用一般采用客户服务器模式,面向连接的应用调用如图所示。根据上述顺序调用函数建立连接后,通信双方便可交换数据1。然而,在调用带*号的函数时,操作常会阻塞,特别是当套接字工作在同步阻塞模式(Bloc

6、king Mode)时。这时,程序无法响应任何消息。为了避免出现这种情况,本文引进辅助线程。在执行含有可能阻塞的函数的任务时,动态创建新的线程,专门处理该任务。主线程把任务交给辅助线程后,不再对辅助线程加以控制与调度。本文分别针对connect()、accept()、receive()、send()等可能阻塞的函数创建了相应的线程,如表1 所示。多线程编程常常还要考虑线程间的通信。线程间的通信可以采用全局变量、指针参数和文件映射等方式。本文采用指针参数方式。在调用AfxBeginThread()函数时,通过传递指针参数的方式在主线程与辅助线程间通信。AfxBeginThread()函数的用法如

7、下:CWinThread*AfxBeginThread (AFXTHREADPROC pfnThreadproc,LPVOID pParam,int nPriority=THREADPRIORITYNORMAL, UINT nStackSixe=0,DWORD dwCreateFlags=0,LPSECURITYATTRIBUTESlpSecurityAttrs=NULL);参数pfnThreadProc 指定线程函数 必须如下定义:UINT MyControllingFunction (LPVOID pParam); 参数pParam 是调用线程传递给线程函数pfThreadProc 的参数

8、;其他参数一般只需采用缺省值。指针参数通信方式就是通过参数pParam 在线程间通信的,它可为指向任何数据类型的指针。本文中,定义了一个名叫EXCHANGEINFO 的结构如下:typedef struct SOCKET sServerSocket; SOCKET *pcCoientSocket; SOCKADDRIN *pClientAddr; BOOL *pbConnected;unsigned char *pucBuffer ;int *pnMessageLen ; EXCHANGEINFO;在需要通信时,先声明一个结构变量,再把变量的指针作为pParam 参数,调用AfxBeginTh

9、read(AFXTHREADPROC) CSocketThread: WaitFor ConnectThread,(LPVOID) mExchangeinfo)函数即可。为了利用面向对象技术编程所具有的模块性强、便于修改、可移植性好等优点,本文还把表1 中的线程封装为父类为CWinThread 的自定义类CSocketThread 中。还自定义了一个叫CSocketComm的新类,封装了一些函数,如CreateSocket、ConnectToServer、WaitForClient、ReadMessage、SendMessage 等,这些函数屏蔽了面向连接的通信程序的实现细节,如创建、连接、发

10、送和接收等,在这些函数里,动态创建辅助线程。下面以CSocketComm 类中的等待客户连接请求的函数WaitForClient()为例,注释说明多线程编程的具体细节。BOOL CSocketComm:WaitForClient if(mbConnected)return ( TRUE ); 配置bind 函数的参数 即服务器的套接字地址结构SOCKADDRIN Addr ;memset(Addr,0,sizeof(SOCKADDRIN); Addrsinfamily=AFINET;ADDRSINport= htonl (mnPort); Addrsinaddrsaddr = htonl(IN

11、ADDRANY); 将套接字地址结构赋予套接字(绑定),以指定本地半相关int nReturnValue;nReturnValue =:bind ( msSserverSocket,( LPSOCKADDR) Addr,sizeof (SOCKADDRIN ); if (nReturnValue = SOCKETERROR) returu ( FALSE ); 配置传给WaitForConnectThread 线程函数的参数mExchangeinfomExchangeinfosServerSocket = msserverSocket; mExchangeinfopsClientSocket

12、= msClientSocket; mExchangeinfopClientAddr = mClientAddr; mExchangeinfopbConnected = mbConnected; 以mExchangeinfo 的指针为参数调用WaitforConnectThread 线程等待客户端连接AfxBeginThread (AFXTHREADPROC) CSocketThread:WaitForConnectThread, (LPVOID) mExchanginfo); returi ( TRUE ) 等待连接线程UINT CSocketThread:WaitForConnectThr

13、ead (LPVOIDpParam) EXCHANGEINFO *pExchangelnfo(EXCHANGEINFO*) pParam; int nReturnValue, nClientAddrSize= Sizeof ( SOCKADDRIN);侦听连接nReturnValue=: listen (pExchangelnfo sServerSocket, 1); if ( nReturnValue = SOCKETERROR ) return (0); 阻塞调用accept,直至有客户连接请求*pExchangelnfopsClitentSocket=: accept (pExchang

14、elnfosServerSocket, (LPSOCKADDR) pEchangelnfo pClientAddr, nClientAddrSize); if ( *pExchangelnfopsClitentSocket)!= INVALIDSOCKET) 通过pExchangelnfo 的指针在线程间通信* pExchangelnfopbConnected TRUE;return ( 0 ); 应用实例高层协议的设计在电厂和电站中,为了保证安全工作,保护系统必不可少。保护系统的电源供应通常使用两种方式。一般情况下,使用交流电系统对保护系统进行供电;当交流电系统出现故障时 立即使用后备的蓄电

15、池系统对保护系统进行供电。为了对蓄电池系统进行监控和管理,以保证蓄电池在关键时刻能正常工作,设计了在Windows NT 环境下具有远程通讯功能和动态人机界面的智能蓄电池远程监控系统。该系统由蓄电池智能管理、充电机控制、母线绝缘在线检测、声光报警、系统组态、远程通信等子系统组成,实现对蓄电池充电机智能化远程管理和控制,对整个系统的运行状态进行实时监控,具有多媒体报警、事件处理、动态数据库、趋势画面和动态画面显示、操作提前提醒等功能。系统框图如图2 所示。在远程通信模块中,远程监控机需把监控客户的操作命令及时传给本地机,本地机根据命令控制充电机,使之按照一定的方式工作,而本地机需定时向远程监控机

16、反馈实时的充电机状态信息。它们之间的通信是基于TCP/IP的广域网通信,而且,我们引进了多线程机制以保证系统具有良好的实时性。下面以其中的充电机控制系统为例谈谈如何使用CSocketComm类进行远程通信。为简单起见,假定本地机与远程监控机之间通信的信息仅有下面三种类型:本地机接收到该命令后,控制充电机按照稳压模式运行,输出电压为电压给定值;本地机接收到该命令后,控制充电机按照稳流定时模式运行,输出电流为电流给定值;本地机向远程监控机发送充电机的实时状态数据(包括输出电压、输出电流、状态指示和故障类型指示)。在基于TCP/IP 的面向连接的网络通信中,客户与服务器之间传送的是有序可靠的字节流(Byte Stream),所以程序员有必要在传输层TCP 上定义自己的高层协议,设计帧结构

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > 多媒体应用

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号