AIS接收数据程序.doc_第1页
AIS接收数据程序.doc_第2页
AIS接收数据程序.doc_第3页
AIS接收数据程序.doc_第4页
AIS接收数据程序.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

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

文档简介

AIS数据接收程序唐存宝 交通信息工程及控制 200377603250一 设计目的:实现AIS经由网络传输的数据接收,并显示在MFC的控件内;同时,为了模仿AIS数据发送的方式,简单设计了AIS发送数据的客户端。二 设计意义:显示解码前的AIS信息,对AIS信息解码,AIS数据库编程打下根基。可以对这些数据进行数理统计,发现其规律,从而更好掌握AIS水域交通流状况。三 基础简介(1) 网络编程基础知识1 通信协议:TCP/UDP/IP协议,一般称为TCP/IP协议。UDP是用户数据报协议,该协议通信时并不建立可靠的连接,所以不能保证数据能否达到,也不知道在什么时间到达,也不能保证数据完整性(即在传输过程中有可能丢失数据);在接收方,数据有可能次序改变,也有可能重复收到一条数据。TCP 是传输控制协议,这是网络应用程序首要的协议。它是一个大块数据无差错输送的协议,即使传输的数据报是以错误的次序到达的,TCP协议却能使数据报按发送的次序重新组合。它包括了HTTP,FTP这两种协议。TCP协议建立了一个在两台计算机之间全双工、点对点的连接。这种连接的每一个端上的程序都使用它自己的端口。IP地址和端口号组合称为一个套接字。总之,TCP协议在通信双方间建立了一条可靠,无数据差错,无数据重复的连接。当然,这不需要我们来完成,由计算机自己来完成。UDP和TCP协议相比,UDP通信会比TCP通信快些,因为UDP通信双方不需要建立连接;而TCP需要建立可靠的连接,因此在一个庞大的聊天室中用UDP协议也未尝不可。但是,对于不容许丢失的数据、非常重要的数据,一般采用TCP协议。2 套接字IP地和端口号组合成一个套接字。好比用固定电话通信一样,要想打电话,你必须有电话机(相当于你有IP),有个电话机,但你还不知道跟哪一部电话通讯,好了,电话号码就指明了我们通讯的电话,也就相当于端口指明了要和我们通信的应用程序。否则,一台电脑上的那么多网络应用程序,谁知道哪一个程序会负责数据的收发工作?电话机和端口就组成了的套接字。好了,有了电话机,应使它处于正常工作状态,也就是侦听状态,以便别人打来电话时,我们能接收。在服务器应用程序上应有一套接字处于侦听状态,以使客户机一有数据请求便能侦听到。基于TCP的流式套接字,不仅要有侦听套接字,而且有连接(通讯)套接字以保证可靠连接。当然,基于UDP的,就不需要这种连接套接字了。3 异步非阻塞通讯和同步阻塞通讯假如有一接收数据的函数,若没有数据到来,它一直等待,其它函数在此时无法执行。直至时此函数接收到数据,它才返回。这样的通信方式就是阻塞的,同时也是同步的(毕竟你必须等待它执行完嘛!)。假如一接收数据函数,有没有数据到来,它立即返回,这就是异步非阻塞方式了。好比一个体育老师测试100名学生400米的成绩,他可以有两种方式来测试:一种方式是:先让第一个学生跑,等跑完后记录时间,再让下一个跑,好了,它跑的过程中,你必须等待,这就是同步;同时,其它同学在这个时间不能跑,这就是阻塞。另一种办法是:先让第一个同学跑,10秒再跑一个,再过10秒又跑一个,这样不用等一个同学跑完又有同学跑,这就是异步,这种方式在一个学生跑时其它学生也不阻挡其它学生跑,这就是非阻塞。4 MFC类(具体是CAsyncSocket,CSocket)屏蔽了TCP/IP的细节,屏蔽了异步同步,阻塞非阻塞的实现细节,对于初学网络编程的可以方便快捷开发网络应用程序。如果要想了解同步、异步、阻塞与非阻塞等,最好还是用WinSock API 函数来编程。事实上,CAsyncSocket,CSocket就是WinSock API的良好封装。CSocket是内载了多线程的机制,不信的话你可以设计一个单击按纽,一旦单击这个按纽就弹出一个模态的消息框。你在数据接收时,点击按纽,消息框弹出,但是接收数据的函数却仍然执行,这就至少说明了两点:CSocket是阻塞的;CSocket类的数据收发实际开辟了另一线程。实际上,一个CSocket类及其派生类的对象中有一个套接字窗口句柄。CSocketWnd各种的网络事件都是由此窗口自发调用的。 (2) AIS有关介绍AIS是工作在VHF海上移动频段,其工作频率为161.975MHz和162.025MHz。它是通过自组织时分多址接入(SOTDMA)的通信协议方式自主地向外播发船舶的静态与动态信息。AIS能够实现船舶、船岸间的船舶标识、位置、航向、航速等航行信息的自动交换,是新一代的海上通信导航系统。安装有AIS的船舶发送的AIS静态、动态和与航次有关的信息内容如表1所示。AIS输出的主要信息的信息种类如表2所示PP。表1 船舶发送的AIS信息静态的动态的与航次有关的海上移动服务识别(MMSI)具有精度指示和完整状态的船舶位置船舶吃水呼号和船名以协调世界时(UTC)标记的定位时间危险货物(种类)IMO编号对地航向(COG)目的港和ETA船长和船宽对地航速(SOG)航线计划(转向点)船舶类型航行状态定位天线的位置旋回速率(ROT)表2 AIS主要信息的结构和种类信息 ID码信 息 名 称信 息 描 述1船位报告定时船位报告2船位报告分配定时船位报告3船位报告讯问船位报告4基站报告基站目前的位置、时间、时隙5静态和航行相关数据定时静态和航行相关数据报告9标准搜救飞行器位置报告参与搜救的飞行器位置报告10UTC/日期响应输出有效的UTC/日期11申请安全相关信息安全相关数据通信12安全相关确认接收到安全相关数据的确认13安全相关的广播信息与安全有关的广播通信AIS船舶信息服务系统的组成由三个部分组成,首先,设在各地的AIS接收机接收船舶自主发送的AIS有关表1所列的AIS信息;其次,将接收到的AIS数据信息进行协议转换处理后数据信息不断地通过互联网络传输到(PUSH)数据中心的数据服务器中;最后,在数据服务器中将AIS数据信息进行解码后,在ECDIS上显示出相关的AIS信息,并向客户端发布。基于ECDIS的AIS船舶信息服务系统的组成框架如图1所示。图2为数据传输的关键技术。图1 基于ECDIS的AIS船舶信息服务系统的组成框架图图2 远程采集AIS数据信息系统框图如图2所示,从AIS接收机到数据服务器传输链路主要分为两个部分。四 设计思想从AIS的介绍中明显可以看出,要设计的程序实际是收集各地AIS的数据信息服务器,不是客户端。用CSocket派生类实现AIS数据接收服务器程序。CAsyncSocket,CSocket为支持异步非阻塞方式,提供了网络事件Network Events。如侦听套接字A侦听到连接请求,侦听套接字A会收到一个OnAccept事件,到这个事件里,你应该调用virtual BOOL Accept( CAsyncSocket& rConnectedSocket, SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL ) 来实现建立连接套接字rConnectedSocket(设为B)。数据到来时,连接套接字B会收到OnRecieve事件,你可以在此事件中调用B的virtual int Receive( void* lpBuf, int nBufLen, int nFlags = 0 );来接收数据放到lpBuf中,你可以在此时把lpBuf显示在编辑框里。在连接中,如遇到网络中断或对方客户端(AIS)关闭了连接套接字,那么B会收到一个OnClose事件,在此事件里你可以调用B.Colse();实现B套接字的关闭,释放其它的资源;最为重要的是,AIS好像移动电台一样,安放的位置一般船舶密度很大,这也就是说传输的数据量很大,把这些数据动态显示在编辑框的框架内可以看到明显的数据在闪烁,在这种情况下为了看清数据,设置了停止监听按纽。上面已经说了,CSocket是内载了多线程机制、提供同步阻塞调用的类。停止监听不算很容易,不仅涉及到一些通信难理解的概念,还有处理内载线程和主线程之间的交互问题。有两种解决办法,一个是基于MFC提供的CSocket成员函数(面向对象),另一种是根据算法来终止监听(面向过程)。为了避开CSocket类中比较难理解的函数,本程序选择了一个算法实现了监听的停止。对于AIS模拟客户端程序,不是主要任务。故从简设计。其主要作用就是为了模拟AIS的数据发送。其主要原理就是定义了一个定时器,在很短的时间内投递并响应WM_TIMER消息,在这个消息响应的函数中,调用了Send函数,因为时间超时设置的较短,故Send执行次数相当多;再者,Send发送的数据,类似于船用AIS发的数据,为了区别,已在各条消息上标上序号。这也就生动模拟了船上发送的AIS信息。但是,限于时间,此客户端功能极少,仅提供AIS类似的数据格式,AIS数据量大之作用,其它作用不具备了。对于AIS如先启用AIS.exe,再启用AISCliemt.exe,点相关内容参见注意事项。五 实现步骤1、利用MFC appwizard 向导建立一个基于对话框程序;注意在第三步是时选中 windows Socket。以加载套接字库资源。 如下图3图3 建立工程时选择Windows Sockets2、生成后添加控件,控件有控件类型控件ID控件文本控件属性处理Static textIDC_STATIC_PORT端口号为8000默认关联CStatic变量Static textIDC_STATIC_IP对方IP:默认Edit BoxIDC_EDIT_RECEIVE勾选Multiline关联CEdit变量ButtonIDC_BTN_HOSTIPNAME本地主机和IP消息响应ButtonIDC_BTN_LISTEN开始监听勾选Disabled消息响应ButtonIDC_BTN_STOPLISTEN停止监听勾选Disabled消息响应ButtonIDC_BTN_CLEARDATA清除数据勾选Disabled消息响应3、定义一个CSocket派生类CLisSocket.添加CAISDlg* 的一个数据成员和OnAccept(),OnReceive(),OnClose()事件响应函数, 并添加得到CAISDlg*一个函数 void SetParent(CAISDlg*)使套接字得到CAISDlg*成员。具体代码如下:void CLisSocket:OnAccept(int nErrorCode) / TODO: Add your specialized code here and/or call the base classCSocket:OnAccept(nErrorCode);m_pDlg-OnAccept(); /使OnAccept事件交由主对话框来处理;void CLisSocket:SetParent(CAISDlg* Dlg)/得到主对话框指针m_pDlg; m_pDlg=Dlg; void CLisSocket:OnClose(int nErrorCode) / TODO: Add your specialized code here and/or call the base classCSocket:OnClose(nErrorCode);Close(); /对方关闭套接字或网络中断时响应;此时套接字已调用了Close()函数,即通讯套接字将不存在,不具有断后自动重新接收数据的功能void CLisSocket:OnReceive(int nErrorCode) /有数据到来时响应,转m_pDlg-OnReceive();/ TODO: Add your specialized code here and/or call the base classCSocket:OnReceive(nErrorCode);if (bStop=false) /bStop是在AISDlg.cpp中定义的全局变量,目的/是根据BOOL bStop的值来决定是不是接收数据,想停止监听时只需设置bStop为 true即可。m_pDlg-OnReceive();4、插入一个新端口对话框。CPortDlg,设置端口;并在CAISDlg:OnInitDialog()中初始化。向CAISDlg中增加CString strText,int m_nPort。strText用来提供编辑框上显示的接收到的字符,也是本程序解码的唯一接口。m_nPort是保存端口设置对话框中所设置的值。BOOL CAISDlg:OnInitDialog()CDialog:OnInitDialog();/ Add About. menu item to system menu./ IDM_ABOUTBOX must be in the system command range.ASSERT(IDM_ABOUTBOX & 0xFFF0) = IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);/ Set the icon for this dialog. The framework does this automatically/ when the applications main window is not a dialogSetIcon(m_hIcon, TRUE);/ Set big iconSetIcon(m_hIcon, FALSE);/ Set small icon/ TODO: Add extra initialization here/初始化成员并设置端口号strText=;m_sClientIP=;CPortDlg dlg;m_Port=8000;if (dlg.DoModal()=IDOK)m_Port=dlg.m_nPort;CString str;str.Format(端口号为%d,m_Port); m_cPort.SetWindowText(str);return TRUE; / return TRUE unless you set the focus to a control5、在CAISDlg中添加成员侦听套接字和连接套接字,添加OnAccept(),OnReceive(),OnClose()以在侦听套接字得到网络事件时转移给对话框来处理。添加void Init()来初始化成员,添加void DisplayData()把数据显示在编辑框内。代码如下:void CAISDlg:OnAccept() CString str; SOCKADDR_IN addr; int len=sizeof(sockaddr); m_listen.Accept(m_connect,(sockaddr*)(&addr),&len);/连接请求到来时获得对方IP。 m_sClientIP=inet_ntoa(addr.sin_addr); char IP50; strcpy(IP,m_sClientIP); str.Format(成功建立连接,对方IP:%s,IP); GetDlgItem(IDC_STATIC_IP)-SetWindowText(str); / MessageBox(接收数据成功);void CAISDlg:OnReceive()/信息到来时调用,实现数据的接收的关键部分 char *pBuf=new char1025; int len=1024; int nReceived; CString strReceived; nReceived=m_connect.Receive(pBuf,len); if (nReceived!= SOCKET_ERROR) / MessageBox(停息成功接收); pBufnReceived=NULL; strReceived=pBuf; delete pBuf; strText=rn+strReceived+strText; DisplayData(); /显示数据 void CAISDlg:Init() /初始化套接字m_connect.SetParent(this);m_listen.SetParent(this);m_listen.Create(m_Port);void CAISDlg:DisplayData() if(strText.GetLength()EnableWindow(true);GetDlgItem(IDC_BTN_LISTEN)-EnableWindow(true);GetDlgItem(IDC_BTN_STOPLISTEN)-EnableWindow(false);CString str;str.Format(已断开同客户IP:%s的连接,m_sClientIP) ;GetDlgItem(IDC_STATIC_IP)-SetWindowText(str);bStop=true; m_listen.Close();m_connect.Close();六 程序功能演示仅提供在一台计算机上演示方法1、用模拟客户端AISClient.exe测试运行AIS.exe,在输入端口对话框中设置端口,比如8000,点击确定。点击开始监听。运行AISClient,点“击连接服务器”。会出现图4状态。客户端和服务器端均出现“成功建立连接字样”;服务器端上部还有与此连接的IP等字样。此时点击客户端的自动发送,将会看到有 “!AIVDM,1,1,A,1P000Oh1IT1svTP2r:43grwboEq4,0*01:18”字样的数据在服务器端快速大批流出;点击服务器端停止监听,对话框上部会有“成功断开连接”的字样。服务器端不能再点击“开始监听”。2、用真正AIS传输过来的数据进行测试。运行AIS.exe,在输入端口对话框中设置端口,比如8000,点击确定。会看到图5对话框。点击开始监听。通过AIS设置软件设置AIS客户端的连接端口为8000,把服务器改成运行

温馨提示

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

评论

0/150

提交评论