VxWorks实现了与BSD4.4 TCP/IP兼容的网络协议栈,并且其实时性较之有很大提高,这使得基于BSD4.4 UNIX Socket的应用程序可以很方便地移植到VxWorks中去。
1.1 VxWorks网络组件

在最底层,vxworks通常使用以太网作为传输媒介。在传输媒介的上一层,vxworks使用TCP/IP和UDP/IP协议,用于vxworks进程与其他主机环境进程之间的传输数据。

在以太网协议之上,提供几种网络工具:

套接字(Sockets)
允许运行在vxworks或其他主机环境下的任务相互通信。
远程调用
允许一个任务唤醒实际上运行在另一台机器上的过程,调用任务和被调用过程可以是运行在vxworks或其他主机开发系统中。
远程文件访问
允许通过网络文件系统NFS、远程shell(RSH)、文件传输协议(FTP)、TFTP访问远程主机上的文件。
文件输出
允许远程主机通过NFS客户端维护vxworks dos文件系统。
远程命令执行
允许任务通过网络调用在主机开发环境上的命令。

支持以下几种物理连接:

  1. 以太网
  2. 串行线接口协议(SLIP and CSLIP)
  3. 除了使用以太网外,vxworks网络能够使用通过串行线连接的串行线接口协议SLIP或者使用压缩头的SLIP协议(CSLIP)与主机通信。使用SLIP或CSLIP作为网络接口驱动是机器间通过长距离电话线连接或RS232串行线点对点连接使用TCP/IP软件的直接方法
  4. 共享内存网络
  5. vxworks网络可以用于同一个底板的多个处理器间相互通信。在这种方式下,数据的传递是通过共享内存进行的。是通过共享网络驱动程序实现的

TCP/IP是vxworks提供的网络间进程通信的主要机制。

主要包括三个协议:Internet协议、IP协议、传输层协议。

    1. Internet协议:处于TCP和UDP之上的一组协议专门开发的应用程序。包括telenet、文件传输协议(ftp)等。
    2. IP层也称网络层,包括Internet协议(IP)、国际控制报文协议ICMP和地址识别协议ARP。

IP协议是TCP/IP协议族的基础。该协议被设计成互连分组交换通信网,已形成一个网际通信环境。它负责在源主机和目的主机之间传输来自其较高层软件的称为数据报文的数据块,它在源和目的地之间提供非连结型传递服务。

网际控制报文协议(ICMP),实际上并不是IP层部分,但直接同IP层一起工作,报告网络上的某些出错情况。允许网际路由器传输差错信息或测试报文。

地址识别协议(ARP)实际上也不是IP层部分,它处于IP层和数据链路层之间,它是在32位IP地址和48位局域网地址之间执行翻译的协议。操作系统用地址解析协议ARP来允许机器将IP地址转变成真正的硬件地址,如以太网地址。

  1. 传输层协议,包括传输层控制协议。主要有TCP和UDP两种协议。TCP:面向连接的传输控制协议;UDP:无连接的用户数据报协议。

IP协议是一个传输层的协议,其他协议可以用它来传输数据。传输控制协议TCP是一个可靠的端对端的协议,它用IP来传送和接收它自己的包。TCP可靠地传送和接收两应用程序间的数据,并保证数据不会丢失。当用IP来传输TCP包时,IP包的数据段就是TCP包。每一个通信主机的IP层负责传送和接收IP包。用户数据报协议(UDP)也用IP层来传输它的包。

TCP/IP协议,涉及到四层:链路层、网络层、传输层和应用层(从下到上),对应OSI七层模型。

其中以太网(Ethernet)的数据帧在链路层。

IP包在网络层,TCP或UDP包在传输层。其中的数据(Data)在应用层。

数据帧{IP包{TCP或UDP包{Data}}}

从下到上:

在链路层,以太网的物理特性决定了数据帧的长度为:(46+18)~(1500+18),其中的18是数据帧的头和尾(目标mac--6字节,源mac--6字节,类型--2字节,FCS--4字节)。即数据帧的内容最大为1500(不包括帧头和帧尾)。MTU:maximun transmission unit为1500.

网络层:IP包首部占20字节,MTU为1480;

传输层:UDP首部占8字节,MTU为1472;大于则发送方的IP层要分片传输,接收方UDP是不可靠的传输协议,如果分片丢失导致重组失败,将导致UDP数据包被丢弃。

高层协议:Telnet协议,用来允许用户远程登录到另一台机器;FTP协议用来传输文件;SMTP协议用来传送email。

IP地址,32位数字。

当应用程序通过TCP/IP进行通信时,不仅要指定目标的IP地址,还要指定应用的端口地址。一个端口地址唯一地标识一个应用,标准的网络应用使用标准的端口地址。

vxworks提供操纵以太网地址的函数,例如将四点地址转换整数地址的函数,从地址中分别提取网络地址部分和主机地址部分的函数,由网络地址和主机地址生成以太网地址的函数等,详见inetLib库。

IP地址实际分为网络地址和主机地址。每部分的长度是可以变化的(有好几类IP地址)。15.32.0.19的网络地址是15.32,主机地址是0.9,主机地址又进一步分为子网地址和主机地址,子网地址是15.32.0,主机地址是15.32.0.9;

1.0.0.0到126.255.255.255为A类 主要分配给具有大量主机而局域网络数量较少的大型网络 ,默认子网掩码是0xff000000;

127.0.0.0--127.255.255.255是保留地址;

128.0.0.0到191.255.255.255为B类 一般用于国际性大公司和政府机构 ,默认子网掩码是0xFFFF0000

192.0.0.0到223.255.255.255为C类 用于一般小公司 校园网 研究机构等 ,默认子网掩码是0xFFFFFF00

C类网络用前三组数字表示网络的地址,最后一组数字作为网络上的主机地址。前三位网络位,第四位主机位。

网络字节序

VxWorks网络字节序按照大端编码。

利用宏实现提高了转换调用效率,并不受CPU体系机构的影响。

h/netinet/in.h
  • htonl 将一个主机长整型数据转换到网络字节顺序
  • htons将一个主机短
  • ntohl将一个网络长整型数据转换到主机字节顺序
  • ntohs将一个网络短整型

套接字

VxWorks用户目前可以使用两种套接字,即流套接字和数据报套接字。

网络编程中最常见的是客户/服务器模式。服务端有一个任务(或多个任务)在指定的端口等待客户来连接,服务程序等待客户的连接信息,一旦连接上后,就可以按设计的数据交换方法和格式进行数据传输。

使用socket调用后,仅产生了一个可以使用的socket描述符,这时还不能进行通信,还要使用其他的调用,以使得socket所指的结构中使用的信息被填写完。

在使用TCP协议时,一般服务端任务先使用socket调用得到一个描述符,然后使用bind调用将一个名字与socket描述符连接起来,对于Internet域就是将Internet地址联编到socket。

之后,服务端使用listen调用指出等待服务请求队列的长度。然后就可以使用accept调用等待客户端发起连接(一般是阻塞等待连接),一旦有客户端发出连接,accept返回客户的地址信息,并返回一个新的socket描述符,该描述符与原先的socket由相同的特性,这时服务端就可以使用这个新的socket进行读写操作。

一般服务端可能在accept返回后创建一个新的任务进行与客户的通信,父任务则再到accept调用处等待另一个连接。

客户端一般先使用socket调用得到一个socket描述符,然后使用connect向指定的服务器上的指定端口发起连接,一旦连接成功返回,就说明已经建立了与服务器的连接,这时就可以通过socket描述符进行读写操作了。

使用无连接的UDP协议时,服务端任务创建一个socket,接着调用recvfrom接收客户端的数据报,然后调用sendto将要返回客户端的消息发送给客户任务。客户端也要先创建一个socket,再使用sendto向服务端任务发出请求,使用recvfrom得到返回的消息。

socket编程接口

socket系统调用

调用socket用来建立一个通信的端点,声明格式如下:

int socket(
int domain,//地址簇
int type,//数据报还是字节流
int protocal//socket protocal 一般是0
)
select调用

select调用及宏FD_CLR、FD_ISSET、FD_SET、FD_ZERO用于同步I/O复用。

该调用和宏定义的声明格式如下:

int selcet(
int width,//number of bits to examine from 0
fd_set *pReadFds,//read fds
fd_set *pWriteFds,//write fds
fd_set *pExceptFds,//exception fds(unsupported)
struct timeval *pTimeOut,//max time to wait ,NULL=forever
)
FD_SET(fd,&fdset)
FD_CLR(fd,&fdset)
FD_ZERO(&fdset)

调用select用来等待一些描述符改变状态。有三个不相关的描述符集合被监测。列在参数pReadFds集合中的描述符监测是否有字符可以从某个描述符读入,列在pWriteFds集合中的描述符监测是否某个描述符准备好了可以立即写入,列在参数pExceptFds集合中的描述符检测是否某个描述符有异常出现。当该调用退出时,集合被指向状态改变的描述符。

FD_CLR、FD_SET、FD_ZERO这三个宏用来操作集合。FD_ZERO用来清空一个集合。FD_SET和FD_CLR用来从一个集合中增加或删除一个描述符。

在select调用中,参数width是三个集合中描述符的最大值。参数pTimeOut是指出select返回的时间限制。当pTimeOut为0时,select调用立即返回。如果参数pTimeOut为空(NULL),select被阻塞。select调用成功时,返回在描述符集合中包含的描述符值,如果返回OK,表示在参数pTimeOut时间里没有描述符改变状态。当发生错误时,返回ERROR,错误发生后,集合和pTimeOut变为没有定义,所以出错后的值是无效的。

当select调用用于socket的费阻塞connect时要注意,一般当一个socket描述符为既可读又可写的状态时,表示发生了错误,但也有可能是该连接在执行到select之前,已经变为可读。这时可以用getsocket的SO_ERROR选项,得到该socket上的错误代码。如果调用正确并且错误代码为0,表示连接正常建立了。否则当socket描述符变为可写时,表示连接正常建立。

该调用用于I/O多路复用的情况,比如一个任务中有多个socket和终端都需要读入数据,而任务并不知道什么时候会有数据出现在哪个描述符上,这时就可以使用select。

Socket的原始方式

vxworks系统提供了socket编程原始方式的接口。在创建socket时选择类型为SOCK_RAW就能创建一个原始类型的socket,在该socket上,程序员可以自己写icmp头、tcp头等来发送原始报文。

ICMP

ICMP提供的差错报告和状态报告服务如下:

  • 生存时间(TTL)超时;
  • 参数不可理解;
  • 报文不可到达;
  • 用于流控的源队列;
  • Echo和Echo应答;
  • 重定向;
  • 时间戳和时间戳应答;
  • 信息请求和信息请求应答;
  • 地址掩码请求和应答。
  • ICMP报文是放在IP报文中的。

一个例子:

Ping使用ICMP协议的强制性ECHO-REQUEST报文来引发某个主机或网关的ICMP协议的ECHO-RESPONSE报文。通过检测返回的数据包的质量以及计算数据包所花的时间就可得出网上两个接点之间网络的通信质量。

在工作时,ping向网上发送ping数据包,并计算收发数据包所用的时间,统计数据包的丢失情况。如果有重复的数据包被接收,它就将其计入收发时间中,这样它重复地执行发包、收包、计算的过程,直到发出的数据包达到指定的数目或者被中断。