Socke Socket t 通讯编程在分布式控制系统中的应用
罗家融 徐浩 朱琳 季振山 田一海 江诲燕
中国科学院等离子体物理研究所  合肥  230031
(e_mail:  jr_luo@mail.ipp.ac)
摘要:分布式控制系统(Distributed Control System 简称DCS DCS)是计算机系统、通讯系统、控制论、信息论socket通信报文格式
与自动化、系统工程、可靠性相互促进、互相接透、综合发展的最好、最高的典范[1]。它自70年代问世以
来,发展异常迅速,已被广泛应用于工矿企业的生产过程控制、核试验、航空航天、核电站、核聚变实验
装置[2]等领域。中国科学院等离子体物理研究所的HT7超导托卡马克核聚变实验装置的控制系统就是一个分布式的控制系统,其主要特征之一是系统中采用了多处理机结构,这就使各处理机之间的数据传送变得十分重要,通讯系统是该控制系统正常运转的支柱。本文较为详细地描述了Socket 通讯方式在该实验装置上的应用。
关键词:分布式控制系统 Socket 通讯技术 以太网
.1.  前言
托卡马克受控热核聚变是人类本世纪替代煤和油的新能源,中国科学院等离子体物理研究所的HT-7超导托卡马克装置其规模和参数介于中小型装置和堆芯装置之间,可以承担聚变工程中有关堆芯连续运行的物理和工程等重大课题的研究。为了实现对整个系统的实时监
控,控制及诊断保护, 该控制系统采用了分布式计算机网络结构[3]。图1是该分布式控制系
统网络结构的示意图。第二部分简单介绍了HT-7控制系统网络的结构,在第三部分介绍了该系统的通讯方式,而第四部分对Socket 编程作了简单介绍,第五部分则给出了一个具体实例,并作出了初步评价,最后是对本文的总结。
2. HT 2. HT--7控制系统网络简解
由于整个HT-7实验控制和数据采集管理系统采用了不同类型的计算机,其操作系统也不相同,各子系统的控制计算机分布在不同的实验现场,彼此相距较远,为了保证控制系统能完成实时的控制,对控制信号和数据的传输速率就有一定的要求的,而且各功能子系统间的数据传输量也比较大。实时通讯是当今网络应用的热点,被广泛应用于数据传输、实时控制、分布处理等诸多领域。通过计算机网络不仅可以进行高速可靠的数据传输,还可以实现资源共享,提高资源的利用率。HT-7实验控制和数据采集管理系
统采用了以局域网为高速数据通道进行连接的通讯方式,将网络通讯技术应用于HT-7实验控制系统数据通讯系统中。由于基于交换器的快速以太网具有性能高和升级方便,性能价格比上具有较明显的优势,且组网技术相对简单,它是目前较好的一种网络选择。基于这种分析,我们选用了基于交换器的快速以太网,网络结构图如图2所示。这样的实验网络从物理结构上看比较合理,不仅交换器的各个端口的负载比较平衡,而且所有跟实验有关的数据通讯问题,都只要在这个实验子网段进行即可,充分体现了局域网的性能。
3.3.HT HT HT--7控制系统数据通讯方式
数据通讯是指通过数据通讯系统将数据以某种方式从一处安全、可靠地传输到另一处。现今,实现计算机之间的数据通讯至少有四种方式:总线连接的通讯方式;调制---解调连接的通讯方式;用过程输入/输出装置连接的通讯方式;高速数据通道连接的通讯方式。计算机控制系统中的通讯往往是各个用于控制的应用程序间的通讯,应用程序之间的数据交换成为数据通讯里的一个重要问题。应用程序的通讯方法有多种方式:文件共享、NetBIOS 编程、标准的Sockets 和WinSock 编程、DCOM 编程等。在HT-7控制网络通讯系统里,主要使用了标准Sockets 编程的数据通讯方法。在TCP/IP 网络环境下的应用程序是通过网络系统编程界面(Sockets )实现的,而Sockets 又利用下层的网络通信协议实现实际的通信工作,它们之间的关系如图3所示。HT-7控制系统中的部分数据通讯正是利用基于TCP/IP 协议的Socket 网络程序来实现, 这些通讯程序是在不同的的操作系统下:VAX 的VMS 系统、路由器的Linux 系统、主
控机的Windows 系统,应用不同的编程语言:Ansi C 、Visaul C++、Delphi 编写而成的, 为用不同语言在不同操作系统下进行Socket 程序开发提供了极好的模型样本。
4.Socket 编程要点
利用socket 进行通信,有两种方式:第一种流方式(Stream  Socket ),亦称面向连接方式。在这种方式下,两个进行通信的应用程序之间先要建立一种虚拟的连接关系,每一次完整的数据传输都要经过建立连接、使用连接和终止连接3个过程,其数据收发顺序一致,且内容相同, 流方式采用TCP 协议。第二种数据报方式(Data gram  Socket ),又称无连接方式。每个数据分组都携带完整的目的地址,各分组在系统中独立传输, 数据报方式采用
UDP协议。
4.1基于客户机/服务器方式的Socket通信主要流程
在网络通信中,由于网络拥挤或一次发送的数据量过大等原因,经常会发生交换的数据在短时间内不能传送完,发送数据的函数不能返回。Socket对有可能阻塞的函数提供了两种处理方式:阻塞和非阻塞方式。在阻塞方式下,收发数据的函数在被调用后一直到传送完毕或者出错才能返回。对于非阻塞方式,函数被调用后立即返回,当传送完成后, 给程序发一个事先约定好的消息。基于TCP/IP网络通信的主
要模式是客户机/服务器(Client/Server)方式,使用Socket进行网络通信程序设计和其它客户机/服务器模式通信应用程序设计过程一样:客户机程序(进程)发送请求给服务器(进程),服务器进程对客户机的请求作出响应,并产生结果。
客户机方应用程序功能为:
(1)打开一通信通道(申请--套接字), 并连接到指定主机上一特定地址向服务器发出请求
报文,等待接收应答。
(2)给服务进程发服务请求报文并接收应答, 只要需要就一直做这一步。
(3)关闭通信通道并终止。
服务器方应用程序功能为:
(1)打开一通信通道并告知本地主机它愿意在某一地址上接收客户请求, 接收到请求,启动
一新进程处理用户请求,同时释放旧进程以响应新的客户请求,一旦完成,关闭新进程与客户的通信链路。
(2)对于一重复服务, 处理该请求并发送应答信息; 对于并发服务, 要激活一新进程来处理
此客户请求. 当完成任务后, 此新进程关闭与客户的通信链路并终止.
(3)返回到第2步, 继续等待客户机请求.
面向连接的基于Socket 的客户机/服务器结构应用程序的基本形式如图4所示。
4.2基于客户机/服务器方式的Socket通信主要函数
以下几个库函数是Socket网络程序设计的核心部分
(1)socket
调用方式:
#include <types.h>
#include <socket.h>
socket(int domain,int type,int protocol);
此函数为通信创建一个端口,正常调用将返回一个文件描述符,错误调用将返回一1。domain 参数有两种选择:AF_UNIX与AF_INET,其中AF_INET为Internet通信协议。type 参数也有两种选择:  SOCK_STREAM 用于TCP,SOCK_DGRAM用于UDP。protocol参数通常为0。
(2)bind
调用方式:
#include <types.h>
#include <socket.h>
#include <stdio.h>
bind(int s,const struct sockaddr *address,size_t address_len);
此函数目的就是把socket返回的套接口端口与网络上的物理位置相关联。bind正常调用返回0,出错返回一1。此函数有三个参数:其中s为socket调用返回的文件描述符,*address 设置了与网络上的物理位置相关的信息,它的类型是struct  sockaddr,但在Internet上它是struct sockaddr_in。在socket.h中struct sockaddr_in定义为:
struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
}
sin_family一般为AF_INET,  sin_port为端口号,由于不使用不同字节顺序的机器必须作
转换,故应使用宏命令htons(host  to  network  short)来转换端口号,sin_addr将置为INADDR_ANY。这三个值设置完成后*address参数才有意义。
(3)listen
调用方式:
#include <types.h>
#include <socket.h>
#include <stdio.h>
bind(int s,int backlog);
本函数使socket端口能够接受从客户机来的连接请求,正常调用返回0,出错返回一1。s 参数为socket产生的文件描述符,backlog为所能接受客户机的最大数目。socket,  bind,listen三个函数的综合调用最终在服务器上产生一个能接受客户机请求的监听文件描述符s。
(4)accept
调用方式:
#include <types.h>
#include <socket.h>
accept(int s,struct sockaddr *address, int *address_len);
此函数在有客户机发出连接请求时,初始化这个连接。正常调用返回与客户机通信的通信文件描述符,
出错返回 -1。参数s为socket调用返回的文件描述符。address将用来存储客户机的信息,此信息由accept填入,当与客户机连接时,客户机的地址与端口将填到此处。address_len是客户机地址长度的字节数,也由accept填入。
(5)connect
调用方式:
#include <types.h>
#include <socket.h>
connect(int s, struct sockaddr *address, size_t, address_len);
客户机调用socket建立传输端口后,调用connect来建立与远程服务器相连的连接线路。
(6)inet_addr
调用方式:
#include <types.h>
#include <socket.h>
#include <arpa/inet.h>
inet_addr(char *addstring);
此函数将字符串addstring表示的网络地址(如192.68.0.1)转换成32位的网络字节序二进制值。
(7) gethostbyname(hostn)
调用方式:
#include <socket.h>
struct hostent FAR *PASCAL FAR
gethostbyname(const char FAR * addr);
此函数返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针。如果没有错误发生返回0。否则它返回SOCKET_ERROR。
(8)send 和 recv
调用方式:
#include <socket.h>
send((socket_handle,buffer_pointer,buffer_length,flag)
recv(socket_handle,buffer_pointer,buffer_length,flag)
send(socket_handle,buffer_pointer,buffer_length,flags);
此两个函数分别负责接收和发送数据,recv从socker_handle(socket句柄,可由socket()函
数返回值得到)接收数据放入buffer_pointer 中,其长度为buffer_length , flag 一般取为0。send 则将buffer_pointer 中数据发送给socket_handle 。
5.HT 5.HT--7网络实时数据通信程序的一个实例简解      本节中我们将介绍HT-7控制系统中利用Socket 通讯的一个应用实例。在本实例中服务程序置于操作系统为Windows NT 4.0的数据服务器上,该服务程序用VC++ 5.0开发而成。而客户程序则置于操作系统为VMS 5.0的,用作于数据采集的VAX 4200 微型计算机上,该客户程序用VAX C 开发而成。下面以客户程序中同Socket 有关的代码为例说明, 如何在Socket 提供的函数基础上, 构造一个真正能由用户程序调用的接口, 以供大家参考。
5.1一个简单的socket 实用通信程序
main()
{
int sock 1, sock2;
static struct sockaddr_in sock 1n;
static struct sockaddr_in retsock 1n;
struct hostent hostentstruct;
struct hostent * hostentptr;
struct timeval wait;
static char hostn[256]="ipv42a.ipp.ac";
char server[20]="202.127.205.59";
int flag, retval, nlength;
unsigned long netaddr;
netaddr=inet_addr(server); /将服务器网络地转换成32位网络字节序二进制值/    if ((sock 1=socket(AF_INET,SOCK_STREAM,0))==-1) /创建一个通信端口/
{
perror("socket");
exit(0);
}
if((hostentptr=gethostbyname(hostn))==NULL)/从客户机的网络地址得到对应的名字和地址信息的结构指针。
{
perror("gethostbyname");
close(sock 1);
}
/*绑定服务器 socket*/
hostentstruct= *hostentptr;
sock 1n.sin_family=hostentstruct.h_addrtype;
sock 1n.sin_port=htons(1888);/设定通信端口号,此端口号必须与服务机设置的端口号一致。
sock 1n.sin_addr=*((struct in_addr *)hostentstruct.h_addr);
retval=bind(sock 1,&sock 1n,sizeof(sock 1n));
if(retval!=0)
{
printf("Bind error!");
exit(0);
}
/*与服务器建立socket 连结*/
if ((sock2=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(0);
}
sock1n.sin_family=AF_INET;
sock1n.sin_port=htons(1888);
sock1n.sin_addr.s_addr=netaddr;
retval=connect(sock2,(struct sockaddr *)&sock1n,sizeof(sock1n));
if
(retval!
=0)
{
printf("Connection failure!");
exit(0);
}
complete = 0;
/*通过Socket与服务器进行数据传送*/
send(sock2, &complete, 4, 0);        /*数据发送开始标志*/
send(sock2, information, 20, 0);
.
complete = 1;
send(sock2, &complete, 4, 0);      /*数据发送结束标志*/
close(sock2);
close(sock1);
}
5.3性能测试
为了测量该客户机/服务器系统的传输性能,特进行了实地测试,在进行测试时,由客
户机VAX4200(75MHZ主频,32MB内存和4GB的硬盘)记录运行情况,并用统计方法得到其运
行参数。而服务器则由操作系统为Windows NT 4.0的双CPU(双PIII-450,内存为128MB)微
机组成,通讯介质是100M以太网。
在客户程序中适当位置加入VMS系统调用SYS$INIT_TIMER与SYS$SHOW_TIMER来记录所
需测量的程序段的运行时间[4]。这样便可以得到被测程序段运行的Elapsed time 与 CPU time。测量从客户机发出连接请求开始计算,直至所要求的全部数据传输完毕。测量参数总
结见下表(所需时间为一个标准通道(24K字节)所花费的时间):
表 VAX4200 完成全部传输的有关测量统计结果(单位:秒)
取数准备 CPU 取数 Disk I/O传输准备CPU 网传准备CPU 网传CPU
0.13 0.15 0.032 0.063 0.09 实测的结果说明数据通过网络传输速率为22M/s左右,与理论值相差5倍左右,其主要原因
是由于没有充分利用客户机的硬件资源所致。为了证实这一点,我们还进行了两台PC(客户
机PIII-5000,128MB内存, 服务器双PIII-450,内存为128MB)在相同条件下的传输实验,
结果可达到76M/s左右。为了在现有系统上提高传输速率,我们在客户机端启动了两个传输
线程,由于充分利用了客户机的CPU运行时间, 传输速率提高了40%。但在启动了三个传输
线程后,传输效率反而降低了。其原因则是VAX微型计算机在频繁切换线程时,反而消耗了
有限的CPU时间。从性能测试的结果说明,必须合理地安排线程才能在硬件资源有限的情况
下充分利用CPU时间,提高Socket的传输速率。
6. 总结
随着网络通讯技术的发展,将Socket通讯技术应用到分布式控制系统中是一种很好的应用
方式,HT-7控制系统中网络通讯系统的建立就是一个很成功的应用。不同操作系统下基于
TCP/IP协议的Socket网络程序的编写,不仅成功地解决了HT-7控制系统中一些数据通讯的
问题,也为今后网络通讯程序的开发提供了良好的范例。本系统组建的一部分经费来源,来
自于中国科学院综合计划局装备处的1998年HT-7超导托卡马克控制系统的升级改造项目,

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。