AIS接收数据程序.docx

上传人:b****4 文档编号:5504434 上传时间:2022-12-17 格式:DOCX 页数:15 大小:25.17KB
下载 相关 举报
AIS接收数据程序.docx_第1页
第1页 / 共15页
AIS接收数据程序.docx_第2页
第2页 / 共15页
AIS接收数据程序.docx_第3页
第3页 / 共15页
AIS接收数据程序.docx_第4页
第4页 / 共15页
AIS接收数据程序.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

AIS接收数据程序.docx

《AIS接收数据程序.docx》由会员分享,可在线阅读,更多相关《AIS接收数据程序.docx(15页珍藏版)》请在冰豆网上搜索。

AIS接收数据程序.docx

AIS接收数据程序

 

AIS数据接收程序

唐存宝交通信息工程及控制3250

 

一设计目的:

实现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异步非阻塞通讯和同步阻塞通讯

假如有一接收数据的函数,若没有数据到来,它一直等待,其它函数在此时

 

1

 

无法执行。

直至时此函数接收到数据,它才返回。

这样的通信方式就是阻塞的,

同时也是同步的(毕竟你必须等待它执行完嘛!

)。

假如一接收数据函数,有没有数据到来,它立即返回,这就是异步非阻塞方式了。

好比一个体育老师测试100名学生400米的成绩,他可以有两种方式来测试:

一种方式是:

先让第一个学生跑,等跑完后记录时间,再让下一个跑,好了,它跑的过程中,你必须等待,这就是同步;同时,其它同学在这个时间不能跑,这

就是阻塞。

另一种办法是:

先让第一个同学跑,10秒再跑一个,再过10秒又跑一个,这样不用等一个同学跑完又有同学跑,这就是异步,这种方式在一个学生跑时其它学生也不阻挡其它学生跑,这就是非阻塞。

4MFC类(具体是CAsyncSocket,CSocket)屏蔽了TCP/IP的细节,屏蔽了异步同步,阻塞非阻塞的实现细节,对于初学网络编程的可以方便快捷开发网络应

用程序。

如果要想了解同步、异步、阻塞与非阻塞等,最好还是用WinSockAPI函数来编程。

事实上,CAsyncSocket,CSocket就是WinSockAPI的良好封装。

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)

表2AIS主要信息的结构和种类

信息ID码

信息名称

信息描述

1

船位报告

定时船位报告

2

船位报告

分配定时船位报告

3

船位报告

讯问船位报告

4

基站报告

基站目前的位置、时间、时隙

5

静态和航行相关数据

定时静态和航行相关数据报告

 

2

 

9

标准搜救飞行器位置报告

参与搜救的飞行器位置报告

10

UTC/日期响应

输出有效的UTC/日期

11

申请安全相关信息

安全相关数据通信

12

安全相关确认

接收到安全相关数据的确认

13

安全相关的广播信息

与安全有关的广播通信

AIS船舶信息服务系统的组成由三个部分组成,首先,设在各地的AIS接收机接收船舶自主发送的AIS有关表1所列的AIS信息;其次,将接收到的AIS

数据信息进行协议转换处理后数据信息不断地通过互联网络传输到(PUSH)数

据中心的数据服务器中;最后,在数据服务器中将AIS数据信息进行解码后,

在ECDIS上显示出相关的AIS信息,并向客户端发布。

基于ECDIS的AIS船舶信息服务系统的组成框架如图1所示。

图2为数据传输的关键技术。

天线

天线

天线

位置1

位置2

位置n

AIS接收机

AIS接收机

AIS接收机

数据协议转换处理

数据协议转换处理

数据协议转换处理

 

INTERNET

 

数据服务器

 

INTERNETINTERNET

 

客户端1客户端2客户端n

 

图1基于ECDIS的AIS船舶信息服务系统的组成框架图

 

RS232

TCP/IP网络

AIS接收机

RS232到TCP/IP协议转换器

波特率38400bit/s

网络参数设置

服务器

IP地址:

192.168.1.120

掩码:

255.255.255.0

网关:

192.168.1.1

 

图2远程采集AIS数据信息系统框图

如图2所示,从AIS接收机到数据服务器传输链路主要分为两个部分。

四设计思想

从AIS的介绍中明显可以看出,要设计的程序实际是收集各地AIS的数据信息服务器,不是客户端。

用CSocket派生类实现AIS数据接收服务器程序。

CAsyncSocket,CSocket

 

3

 

为支持异步非阻塞方式,提供了网络事件NetworkEvents。

如侦听套接字A侦听到连接请求,侦听套接字A会收到一个OnAccept事件,到这个事件里,你应该调用virtualBOOLAccept(CAsyncSocket&rConnectedSocket,SOCKADDR*lpSockAddr=NULL,int*lpSockAddrLen=NULL)来实现建立连接套接字rConnectedSocket(设为B)。

数据到来时,连接套接字B会收到OnRecieve事件,你可以在此事件中调

用B的virtualintReceive(void*lpBuf,intnBufLen,intnFlags=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、利用MFCappwizard向导建立一个基于对话框程序;注意在第三步是时选中windowsSocket。

以加载套接字库资源。

如下图3

 

图3建立工程时选择WindowsSockets

 

4

 

2、生成后添加控件,控件有

控件类型

控件ID

控件文本

控件属性

处理

Statictext

IDC_STATIC_PORT

端口号为8000

默认

关联CStatic变量

Statictext

IDC_STATIC_IP

对方IP:

默认

EditBox

IDC_EDIT_RECEIVE

勾选Multiline

关联CEdit变量

Button

IDC_BTN_HOSTIPNAME

本地主机和IP

消息响应

Button

IDC_BTN_LISTEN

开始监听

勾选Disabled

消息响应

Button

IDC_BTN_STOPLISTEN

停止监听

勾选Disabled

消息响应

Button

IDC_BTN_CLEARDATA

清除数据

勾选Disabled

消息响应

3、定义一个CSocket派生类CLisSocket.添加CAISDlg*的一个数据成员和OnAccept(),OnReceive(),OnClose()事件响应函数,并添加得到CAISDlg*一个函数voidSetParent(CAISDlg*)使套接字得到CAISDlg*成员。

具体代码如下:

voidCLisSocket:

:

OnAccept(intnErrorCode)

{//TODO:

Addyourspecializedcodehereand/orcallthebaseclassCSocket:

:

OnAccept(nErrorCode);

m_pDlg->OnAccept();//使OnAccept事件交由主对话框来处理;

}

voidCLisSocket:

:

SetParent(CAISDlg*Dlg)//得到主对话框指针m_pDlg;

{

m_pDlg=Dlg;

}

voidCLisSocket:

:

OnClose(intnErrorCode)

{//TODO:

Addyourspecializedcodehereand/orcallthebaseclass

CSocket:

:

OnClose(nErrorCode);

Close();//对方关闭套接字或网络中断时响应;此时套接字已调用了Close()函

数,即通讯套接字将不存在,不具有断后自动重新接收数据的功能

}

voidCLisSocket:

:

OnReceive(intnErrorCode)//有数据到来时响应,转m_pDlg->OnReceive();

{

//TODO:

Addyourspecializedcodehereand/orcallthebaseclassCSocket:

:

OnReceive(nErrorCode);

if(bStop==false)//bStop是在AISDlg.cpp中定义的全局变量,目的

//是根据BOOLbStop的值来决定是不是接收数据,想停止监听时只需设置bStop为true即

可。

{

m_pDlg->OnReceive();

}

4、插入一个新端口对话框。

CPortDlg,设置端口;并在CAISDlg:

:

OnInitDialog()

中初始化。

向CAISDlg中增加CStringstrText,intm_nPort。

strText用来提供编辑框上显示的接收到的字符,也是本程序解码的唯一接口。

m_nPort是保存端口设置对话框中所设置的值。

BOOLCAISDlg:

:

OnInitDialog()

{

 

5

 

CDialog:

:

OnInitDialog();

//Add"About..."menuitemtosystemmenu.

//IDM_ABOUTBOXmustbeinthesystemcommandrange.ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX<0xF000);

CMenu*pSysMenu=GetSystemMenu(FALSE);if(pSysMenu!

=NULL)

{

CStringstrAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBOX);

if(!

strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,

strAboutMenu);

}

}

 

//Settheiconforthisdialog.Theframeworkdoesthisautomatically

//whentheapplication'smainwindowisnotadialog

SetIcon(m_hIcon,TRUE);//Setbigicon

SetIcon(m_hIcon,FALSE);//Setsmallicon

 

//TODO:

Addextrainitializationhere

 

//初始化成员并设置端口号

strText="";

m_sClientIP="";

CPortDlgdlg;

m_Port=8000;

if(dlg.DoModal()==IDOK)

{

m_Port=dlg.m_nPort;

CStringstr;

str.Format("端口号为%d",m_Port);

m_cPort.SetWindowText(str);

}

returnTRUE;//returnTRUEunlessyousetthefocustoacontrol

}

5、在CAISDlg中添加成员侦听套接字和连接套接字,添加OnAccept(),OnReceive(),

OnClose()以在侦听套接字得到网络事件时转移给对话框来处理。

添加voidInit()来初始化成

员,添加voidDisplayData()把数据显示在编辑框内。

代码如下:

voidCAISDlg:

:

OnAccept()

{

 

6

 

CStringstr;

SOCKADDR_INaddr;

intlen=sizeof(sockaddr);

m_listen.Accept(m_connect,(sockaddr*)(&addr),&len);//连接请求到来时获得对方IP。

m_sClientIP=inet_ntoa(addr.sin_addr);

charIP[50];

strcpy(IP,m_sClientIP);

str.Format("成功建立连接,对方IP:

%s",IP);

GetDlgItem(IDC_STATIC_IP)->SetWindowText(str);

 

//MessageBox("接收数据成功");

 

}

voidCAISDlg:

:

OnReceive()//信息到来时调用,实现数据的接收的关键部分

{

char*pBuf=newchar[1025];

intlen=1024;

intnReceived;

CStringstrReceived;

nReceived=m_connect.Receive(pBuf,len);

if(nReceived!

=SOCKET_ERROR)

{

//MessageBox("停息成功接收");pBuf[nReceived]=NULL;strReceived=pBuf;

deletepBuf;

 

strText="\r\n"+strReceived+strText;

DisplayData();//显示数据

 

}

voidCAISDlg:

:

Init()//初始化套接字

{

 

m_connect.SetParent(this);

m_listen.SetParent(this);

m_listen.Create(m_Port);

}

 

voidCAISDlg:

:

DisplayData()

{

if(strText.GetLength()<2000)//显示数据的编辑框有限,strText过大没有意义

{

m_cRecv.SetWindowText(strText);

 

7

 

UpdateData(false);

}

else

{

strText.Left(2000);

 

m_cRecv.SetWindowText(strText);

UpdateData(false);

}

}

6、停止监听和清除数据。

刚才已经讲过,接收数据要在bStop为false情况下,那么单

击了“停止监听”按纽后,根据下列代码,bStop为true,将不在接收数据。

同时删除了监

听和连接套接字资源。

voidCAISDlg:

:

OnBtnStoplisten()

{

//TODO:

AddyourcontrolnotificationhandlercodehereGetDlgItem(IDC_BTN_CLEARDATA)->EnableWindow(true);GetDlgItem(IDC_BTN_LISTEN)->EnableWindow(true);GetDlgItem(IDC_BTN_STOPLISTEN)->EnableWindow(false);

CStringstr;

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,把服务器改成运行AIS.exe的IP。

点击开始监听,此时会看到如图6所示的AIS船舶信息。

点击“停止监听”,AIS数据停止接收;出现图7。

单击“清除数据”,出现图8。

此时还可以点击“开始监听”再次进行监听。

 

8

 

图4点击连接服务器后状态

 

图5开始监听前的AIS对话框

 

图6“开始监听”后的对话框

 

9

 

图7停止监听的对话框

 

图8点击清除数据之后的对话框

七注意事项

1、模拟客户端AISClient设计非常简单,只是提供了一种类似AIS数据的发送方式,此种发送方式在在程序内部定义了一个定时器,在很短的时间过后就发送数据。

那么AIS.exe就可以接收数据

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1