基于Winsock的主从式通信vb60系统设计.docx

上传人:b****8 文档编号:9151272 上传时间:2023-02-03 格式:DOCX 页数:19 大小:168.90KB
下载 相关 举报
基于Winsock的主从式通信vb60系统设计.docx_第1页
第1页 / 共19页
基于Winsock的主从式通信vb60系统设计.docx_第2页
第2页 / 共19页
基于Winsock的主从式通信vb60系统设计.docx_第3页
第3页 / 共19页
基于Winsock的主从式通信vb60系统设计.docx_第4页
第4页 / 共19页
基于Winsock的主从式通信vb60系统设计.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

基于Winsock的主从式通信vb60系统设计.docx

《基于Winsock的主从式通信vb60系统设计.docx》由会员分享,可在线阅读,更多相关《基于Winsock的主从式通信vb60系统设计.docx(19页珍藏版)》请在冰豆网上搜索。

基于Winsock的主从式通信vb60系统设计.docx

基于Winsock的主从式通信vb60系统设计

第一章需求分析

1.1课程设计的目的

此次的课程设计是通过主从式通信来了解和掌握简单的通信协议,是作为本学期学习嵌入式Linux网络体系结构设计与TCP/IP协议栈的一次实际应用,有助于深入的了解通信协议的具体实现方式。

这次的课程设计目的是加深对所学知识的了解和掌握,比如TCP协议和UDP协议的所用场合和不同之处;学习到对巡回检测系统的设计方法;同时自己学习了解和掌握对VB开发环境的一些基本的简单的常识,当然也增强了动手能力,为今后的设计做铺垫。

1.2系统实现的具体功能

巡回检测是计算机远程监控系统的一种工作模式。

计算机远程监控系统通常由主站和分站构成,是典型的主-从式通信系统。

正常情况下,巡回检测模式采用一问一答的方式进行,当分站发生异常时可主动上报(例如报警)。

具体要求如下:

1.设1个主站(Server)

2.设8个分站(Client,也可少于8个,但必须多于3个)

3.系统应设置巡检周期和分站采样时间间隔

4.系统的工作模式为:

自动巡检+主动上报

5.可指定(供参考):

远程主机地址:

127.0.0.1;(主站和分站)

本地端口号:

10000;(主站)

10001~10008;(分站)

6.分别设计主站(Server)通信程序和分站(Client)通信程序,界面如示例所示。

7.建议使用VB6.0或VC++编程,也可以用其它编程环境实现。

1.3系统的主要特点

本设计主站是主动呼叫方,主站按周期向各个从站端口发送信息,从站收到信息后作出应答。

当从站发生异常时要主动向主站报告。

从站程序可以同时打开多个。

基于VB6.0的UDP通信示,使用的控件对象有:

标签(Label),文本框(Textbox),命令按钮(Command),通信(Winsock),形状(Shape),定时器(Timer)等几个控件。

第1章主从是通信概要

2.1主从式通信的原理

主从式多机通信即是指主机发送的信息可以传送到各个从机或指定的从机,而各个从机的信息只能发送给主机.主机采用查询方式接收发送数据,从机采用中断方式接收发送数据

2.2主从式通信的特点

1、传输方式灵活、速度快:

1)系统传输平台采用采用工业以态网+现场CAN总线多主传输。

即:

根据矿的具体情况,可采用主从式RS485传输或TCP/IP以太网传输。

2)通讯速率高,传输距离远,抗干扰和雷击能力强。

由于系统采用光信号传输,改进了传统电信号传输时经常被雷击的情况,不需要传输线路避雷器。

3)采用先进的多主并发通讯模式,系统检测速度快,实时性强;

4)彻底突破了低速总线下的技术瓶颈,系统节点容量大大增加;

5)能进行语音、数据、图象的综合传输,快速进行压缩及解压缩处理;

6)系统支持冗余环网工作模式,故障自愈时间短,通信可靠;主从式和多主式煤矿监控系统性能比较见下:

分站容量传输速率实时性传输距离稳定性兼容性传输信息

主从式系统64台2400bps<=30s<=15km一般差数据

多主系统1000台10/100Mbps2s<=40km好好多媒体

二、采用变值变态记录方式:

“变值变态记录”顾名思义就是在测点数值或状态改变时进行记录,“变值变态记录”优于“定时记录”。

变值变态记录具有两方面的优点:

1)当测点数值保持不变或变化范围较小的情况下,不需要重复记录这些相同或基本相同的数值,变值变态记录就使这些重复的记录减少到最低程度;

2)当测点数值变化较大、较快时,又可详细记录每一变化的细节。

而对于“定时记录”在上述两种情况下,则分别会出现重复记录和丢失记录的情况。

三、异地控制比传统的灵活:

一个测点可关联64个异地断电(理论上可关联本系统所有异地控制量)。

1)一控一:

一个瓦斯测点超限,控制一个断电器断电;当此瓦斯测点恢复正常后恢复供电。

2)一控多:

一个瓦斯测点超限,可以控制一个以上的断电器断电;当此瓦斯测点恢复正常后将被控制断电的断电器全部恢复。

3)多控一:

当多个瓦斯测点中的任意一个测点超限,就控制断电器断电;而当这几个瓦斯测点都恢复正常后,才将断电器恢复。

当被控控制量测点未定义时,不进行程序控制。

对于同一个被控通道,当手动控制后,程序控制不再起作用(无论断电还是恢复),直到手动控制解除;当程序控制后(无论断电还是恢复),手动控制仍可起作用。

即所谓的“手动控制高于程序控制”。

四、系统容量大:

1)本系统分站采用8开8模(可互换)8控(如下图所示)。

可同时接入16个模拟量或者16个开关量,给矿上使用带来了很大的灵活性,也节约了成本。

2)系统采用TCP/IP协议传输时理论上一个IP段可接入256个IP地址,而一个IP地址同时对应4个分站通讯,所以可接大于1000个分站。

3)由于分站可接入8个模拟量,当把分站用做抽放计量时,一个分站可同时接入4套抽放(抽放一般由压力传感器、差压传感器(或流量计)、温度传感器、甲烷传感器四个传感器组成)。

五、图形采用矢量图:

可无极限放大缩小,传统软件由于采用位图,图形放大时出现模糊失真。

本系统完全改进了图形放大时出现失真问题。

2.3Winsock编程的原理

通过Winsock可实现点对点或广播通信程序,实际这两者之间的区别不大,编程时其程序流程所用代码几乎相同,不同的地方在于目标地址选择的不同。

并以客户/服务器形式来构建通过Winsock进行通信的点对点通信,并对通信过程的两点分别命名Server和Client。

  

为更清楚的说明出Winsock的结构原理,下面以电信局的普通电话服务为比较对象进行说明:

  

    1、电信局提供电话服务类似版主们这的Server,普通电话用户类似版主们这的Client。

  

    2、首先电信局必须建立一个电话总机。

这就如果版主们必须在Server端建立一个Socket(套接字),这一步通过调用socket()函数实现。

  

    3、电信局必须给电话总机分配一个号码,以便使用户要拨找该号码得到电话服务,同时接入该电信局的用户必须知道该总机的号码。

同样,版主也在Server端也要为这一套接字指定一port(端口),并且要连接该Server的Client必须知道该端口。

这一步通过调用bind()函数实现。

  

    4、接下来电信局必须使总机开通并使总机能够高效地监听用户拨号,如果电信局所提供服务的用户数太多,你会发现拨打电信局总机老是忙音,通常电信局内部会使该总机对应的电话号码连到好几个负责交换的处理中心,在一个处理中心忙于处理当前的某个用户时,新到用户可自动转到一下处理中心得到服务。

同样版主们的Server端也要使自己的套接口设置成监听状态,这是通用listen()函数实现的,listen()的第二个参数是等待队列数,就如同你可以指定电信局的建立几个负责交换的处理中心。

  

    5、用户知道了电信局的总机号后就可以进行拨打请求得到服务。

在Winsock的世界里做为Client端是要先用socket()函数建立一个套接字,然后调connect()函数进行连接。

当然和电话一样,如果等待队列数满了、与Server的线路不通或是Server没有提供此项服务时,连接就不会成功。

  

    5、电信局的总机接受了这用户拨打的电话后负责接通用户的线路,而总机本身则再回到等待的状态。

Server也是一样,调用accept()函数进入监听处理过程,Server端的代码即在中处暂停,一旦Server端接到申请后系统会建立一个新的套接字来对此连接做服务,而原先的套接字则再回到监听等待的状态。

  

    6、当你电话挂完了,你就可以挂上电话,彼此间也就离线了。

Client和Server间的套接字的关闭也是如此;这个关闭离线的动作,可由Client端或Server端劝嬷骰方先关闭。

有些电话查询系统不也是如此吗?

关闭套接字的函数为  

closesocket()  

从以上情况可以看出在服务器端建立一个套接字,并进入实际的监听步骤的过程如下:

socket()->bind()->listen()->accept()  

那么在accept()完了后,版主们说在Server端将生成一个新的套接字,然后Server将继续进入accept()状态,版主们该如何用这个新的套接字来进行与Client端的通信呢,这就用到了recv()函数,而Client端则是通过send()函数来向服务器发信息的。

  

在客户端也是采取类似的过程,其调用Winsock的过程如下:

  

    socket()->connect()->send()  

    首先建立一个socket,然后用connect()函数将其与Server端的socket连接,连接成功后调用send()发送信息。

2.4Winsock编程的实现方法

本次设计是利用Winsock控件对象实现基于UDP通信协议的主从式通信,为了传输数据,首先要设置客户计算机的 Local Port 属性。

然后,服务器计算机只需将 Remote Host 设置为客户计算机的 Internet 地址,并将 Remote Port 属性设置为跟客户计算机的 Local Port 属性相同的端口,并调用 Send Data 方法来着手发送信息。

于是,客户计算机使用 Data Arrival 事件内的 Get Data 方法来获取已发送的信息。

 

主要使用的方法有Send Data 方法和Get Data 方法,在调用 Send Data 方法来着手发送信息时要先设定相同的端口;当传进 UNICODE 字符串并在网络上发送出去之前,将转化成 ANSI 字符串。

Get Data 方法是获取当前的数据块并将其存储在变体类型的变量中。

通常与Data Arrival 事件并用。

2.4.1创建第一个UDP服务器端

确定远程主机属性为对方的计算机名主站为UPDA;

确定远程主机属性为第二个控件的本地端口属性;

调用约定方法指定要被使用的本地端口。

创建一个的UDP连接端

创建一个标准EXE工程;

将默认窗体命名为主站;

在窗体中添加一个Winsock控件,命名为UDPA;

在属性(Properties)页,单击协议(Protocol),改为UDPProtocol;

添加5个文本框控件窗体中,分别命名为txtSend,txtOutput,Text2,Text3,Text5;

添加8个shape控件窗体中,Index属性设置为1,2,3,4,5,6,7,8。

添加4个Command控件窗体中,定义清除数据,发送,开始,结束。

2.4.2创建第二个UDP连接端

添加标准窗体到工程中;

将窗体名改为从站;

将窗体标题改为从站;

在窗体中添加一个Windsock控件并命名为UDPB;

在属性页中单击Protocol,改为UDPProtocol;

添加5个文本框到窗体中,分别命名为txtSend和txtOutput,Text1,Text2,Text3;

添加2个Command控件窗体中,定义清除数据,发送数据。

2.5TCP/IP协议

2.5.1TCP/IP的通讯协议

简要介绍一下TCP/IP的内部结构,TCP/IP协议组之所以流行,部分原因是因为它可以用在各种各样的信道和底层协议(例如T1和X.25、以太网以及RS-232串行接口)之上。

确切地说,TCP/IP协议是一组包括TCP协议和IP协议,UDP(UserDatagramProtocol)协议、ICMP(InternetControlMessageProtocol)协议和其他一些协议的协议组。

2.5.2TCP/IP-整体构架

TCP/IP协议并不完全符合OSI的七层参考模型。

传统的开放式系统互连参考模型,是一种通信协议的7层抽象的参考模型,其中每一层执行某一特定任务。

该模型的目的是使各种硬件在相同的层次上相互通信。

这7层是:

物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。

而TCP/IP通讯协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。

这4层分别为:

应用层:

应用程序间沟通的层,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等。

2.6UDP协议

UDP(UserDatagramProtocol)是一种无连接协议不保证可靠的传输层协议。

与TCP操作不同,计算机间并不需要建立一个连接,同时,一个UDP应用可同时作为应用的客户或服务器方。

由于UDP协议并不需要建立一个明确的连接,因此建立UDP应用要比建立TCP应用简单得多。

UDP与TCP位于同一层,但对于数据包的顺序错误或重发。

因此,UDP不被应用于那些使用虚电路的面向连接的服务,UDP主要用于那些面向查询---应答的服务,例如NFS。

相对于FTP或Telnet,这些服务需要交换的信息量较小。

使用UDP的服务包括NTP(网络时间协议)和DNS(DNS也使用TCP)。

欺骗UDP包比欺骗TCP包更容易,因为UDP没有建立初始化连接(也可以称为握手)(因为在两个系统间没有虚电路),也就是说,与UDP相关的服务面临着更大的危险。

2.7为了提高效率通常采用UDP作为实时数据传输协议的原因

通常,你要创建的应用程序的类别就决定了你要选择的协议。

当发送或接收数据时,该应用程序如果需要从服务端或客户端获得认证,,那么TCP协议就正好需要在发送或接受数据前建立明确的连接。

要发送的数据量大(就像图片、声音文件之类)一旦建立了连接,TCP协议就会保持连接并保证数据的完整性。

但是,这种连接会占用的更多的处理器资源,成本也会更高一些。

数据是陆续传输的,还是一次全部传完呢?

如果要创建的应用程序在某些任务完成时会告知具体的计算机,那么选择UDP协议会更合适一些。

UDP协议也更适合于发送小量数据。

TCP是一种面向连接的的通信协议,UDP(用户数据文报协议)是一个无连接协议。

因此在工业应用中,为了提高效率通常采用UDP作为实时数据传输协议。

第2章总体设计

3.1系统方案

本次设计是实现1个主站和8个从站的通信,主站的端口号为10000,1到5号从站的端口为10001~10008。

结构如下图所示:

图3.1主从站结构图

主站每隔一段时间从1号从站到5号从站依次发送一次巡检信息,从站收到信息就做出相应的回应,在从站之间还有一定的间隔。

流程图如下:

图3.2主从站流程图

第3章详细设计

4.1系统界面

主站的工作显示界面,如下图4.1所示:

图4.1主站工作设计界面

从站工作显示界面如图4.2所示:

图4.2从站工设计作界面

4.2部分代码及说明

4.2.1主站主动向从站发送数据模块 

PrivateSubCommand1_Click()

UDPA.RemoteHost="127.0.0.1"

UDPA.RemotePort=10000+Text3.Text

UDPA.SendDatatxtSend.Text

EndSub

主要作用:

此代码由Command1_Click()事件触发,根据Text3Text中的用户输入主动设置UDPA.RemotePort,并发送txtSend..Text中用户输入的字符串到相应的端口,然后清空输入框和端口框的数据。

4.2.2主站UDPA_DataArrival事件

PrivateSubUDPA_DataArrival_

(ByValbytesTotalAsLong)

IfbytesTotal>2Then

DimstrDataAsString

OnErrorResumeNext

UDPA.GetDatastrData

txtOutput.Text=txtOutput.Text&Chr(13)&Chr(10)&strData

Shape1(UDPA.RemotePort-10000).FillColor=&HC000&

EndIf

EndSub

主要作用:

如果收到的字节大于2执行GetData 并将收到的数据在txtOutput文本框中输出,并将相应的Shape1(Winsock1.RemotePort - 10001)图形填充为红色。

4.2.3从站UDPBDataArrival事件

PrivateSubUDPB_DataArrival_

(ByValbytesTotalAsLong)

IfbytesTotal>2Then

DimstrDataAsString

UDPB.GetDatastrData

txtOutput.Text=txtOutput.Text&Chr(13)&Chr(10)&strData

UDPB.RemoteHost="127.0.0.1"

UDPB.RemotePort=10000

UDPB.SendDataText1.Text&"号站应答"

EndIf

EndSub

主要作用:

当从站接收到数据大于2时执行GetData 方法,并将接收到的数据在txtOutput中显示,还要在接受到主站发来的数据后向主站发送应答

UDPB.SendData Label4.Caption & "号站应答"。

4.2.4巡回检测代码块Timer事件

PrivateSubTimer1_Timer()

Fora=10001To10008

UDPA.RemoteHost="127.0.0.1"

UDPA.RemotePort=a

Shape1(UDPA.RemotePort-10000).FillColor=&H0&

UDPA.SendData"主站巡检"&a-10000&"号站"

DoEvents

Sleep10000

Nexta

EndSub 

 "主站巡检" & RPort-10000 & "号站"     DoEvents      Sleep 100 Next i End Sub 

每隔Timer1.Interval时间执行一次改代码块,每次执行时利用For循环将UDPA.RemotePort设置为从10001到10008间的数,并且执行UDPA..SendData "主站巡检" & a- 10000 & "号站"向当前端口发送数据。

循环体每执行一次Sleep 300,每5s钟检测一次。

4.3系统运行部分截图

4.3.1主站自动巡检

主站作自动巡检时工作截图,点击开始按钮主站自动巡检,当前有1,3,8三个从站在,当主战巡检时,1,3,8分别响应如图4.1—4.4图所示:

图4.1主站每5秒钟检测一次

图4.2从站1被检测到并作出响应

图4.3从站3被检测到并作出响应

图4.4从站8被检测到并作出响应

4.3.12主站手巡检

当主站进行手动巡检时,,首先要在远程端口处先设置好从站端口号(端口号为1—8任意数字)和传送命令(大于2个字节)如图4.5所示,然后点击发送按钮从站会做出响应如图4.5—4.6所示:

图4.5主站手动巡检

图5.6主站手动巡检从站1作出响应

第4章主从是通信中的冲突

主动上报就是从站发生异常时主动向主站发送相应的数据,便于主站及时的采取相应的措施来解决异常。

但是,主动上报也是有一定的弊端的,当多台主机同时发生异常,又同时上报的话,就可能产出冲突。

主站不能同时受理这些上报信息。

解决这种冲突可以采取分割时间片的方法,为每个从站分配一个时间片,在相应从站的时间片内产生的异常可以上报,主站予以处理;反之,不允许上报,当然主站也不会处理的,要等到下一个时间片到来的时候才可以上报,这样才可以解决此冲突。

 

第6章代码

6.1UDPA主站设计的代码

PrivateDeclareSubSleepLib"kernel32"(ByValdwMillisecondsAsLong)

PrivateSubCommand1_Click()

UDPA.RemoteHost="127.0.0.1"

UDPA.RemotePort=10000+Text3.Text

UDPA.SendDatatxtSend.Text

EndSub

PrivateSubCommand2_Click()

Timer1.Enabled=True

EndSub

PrivateSubCommand3_Click()

Timer1.Enabled=False

ForRPort=10001To10008

UDPA.RemoteHost="127.0.0.1"

UDPA.RemotePort=RPort

Shape1(UDPA.RemotePort-10000).FillColor=&H0&

NextRPort

UDPA.Close

EndSub

PrivateSubCommand4_Click()

txtOutput.Text=""

EndSub

PrivateSubForm_Load()

WithUDPA

RemoteHost="127.0.0.1"

.Bind10000

strvar1=InputBox("在下面文本框中输入主站本地端口号","设置本地端口号")

Timer1.Enabled=0

EndWith

EndSub

PrivateSubTimer1_Timer()

ForRPort=10001To10008

UDPA.RemoteHost="127.0.0.1"

UDPA.RemotePort=RPort

Shape1(UDPA.RemotePort-10000).FillColor=&H0&

UDPA.SendData"主站巡检"&RPort-10000&"号站"

DoEvents

Sleep100

NextRPort

EndSub

PrivateSubtxtOutput_Change()

txtOutput.SelStart=Len(txtOutput.Text)

EndSub

PrivateSubUDPA_DataArrival_

(ByValbytesTotalAsLong)

IfbytesTotal>2Then

DimstrDataAsString

OnErrorResumeNext

UDPA.GetDatastrData

txtOutput.Text=txtOutput.Text&Chr(13)&Chr(10)&strData

Shape1(UDPA.RemotePort-10000).FillColor=&HC000&

EndIf

EndSub

6.2UDPB从站设计的代码

PrivateSubCommand1_Click()

UDPB.SendDatatxtSend.Text

EndSub

PrivateSubCommand2_Click()

txtOutput.Text=""

EndSub

PrivateSubForm_Load()

strvar=InputBox("在下面文本框中输入本地站口号1~8","设置本地站号")

Text1

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

当前位置:首页 > 高等教育 > 医学

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

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