首页 理论教育工业以太网应用技术:TCP程序设计

工业以太网应用技术:TCP程序设计

【摘要】:TCP连接的每一方都有固定大小的缓冲空间。这几点也是用户实现TCP协议的几个重点,也是程序实现的基本原则。如果将字节流看做在两个应用程序间的单向流动,则TCP用序号对每个字节进行计数。TCP或UDP连接唯一地使用每个信息中的如下四项进行确认。状态转移图是整个TCP软件设计的灵魂,将状态和作用于状态的事件相联系。图9-20 TCP状态转移图4)在SYN_RCVD状态时,服务器T

TCP(传输控制协议)是TCP/IP协议族中最重要的协议之一,它位于网络层(IP)之上的传输层中,为应用层提供面向连接的、可靠的字节流服务。面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前,必须先建立一个TCP连接。TCP实现的关键就是如何在无连接且不可靠的IP层协议上建立一个面向连接和可靠的协议,这也是实现过程中的难点。TCP通过下列方式来提供可靠性

1)应用数据被分割成TCP认为最适合发送的数据块,应用程序产生的数据报长度将保持不变。

2)当TCP发出一个报文段后,它启动一个定时器等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

3)当TCP收到发自TCP连接另一端的数据,它将发送一个确认。

4)TCP在传送的时候将添加校验和,这是一个端到端的校验和,目的是检测数据在传输过程中是否有变化。如果收到段的校验和有差错,TCP将丢弃这个报文段和不确认收到此报文段(希望发送端超时并重发)。

5)既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。既然IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。

6)TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。

TCP将用户数据打包构成报文段,它发送数据后启动一个定时器,另一端对收到的数据进行确认,对失序的数据重新排序,丢弃重复数据,TCP提供端到端的流量控制,并计算和验证一个强制性的端到端校验和。这是TCP协议工作的一个大概的步骤。这几点也是用户实现TCP协议的几个重点,也是程序实现的基本原则。TCP数据被封装在一个IP数据报中,如果不计任选字段,它通常是20个字节。

每个TCP段都包含源端和目的端的端口号,用于寻找发送端和接收端应用进程。这两个值加上IP首部中的源端IP地址和目的端IP地址,唯一确定一个TCP连接。

序号用来标识从TCP发送端向TCP接收端发送的数据字节流,它表示在这个报文段中的第一个数据字节。如果将字节流看做在两个应用程序间的单向流动,则TCP用序号对每个字节进行计数。序号是32bit的无符号数,序号到达232-1后又从0开始。

当建立一个新的连接时,SYN标志变1。序号字段包含由这个主机选择的该连接的初始序号ISN(Initial Sequence Number)。该主机要发送数据的第一个字节序号为这个ISN加1,因为SYN标志消耗了一个序号。既然每个传输的字节都被计数,确认序号包含发送确认的一端所期望收到的下一个序号。因此,确认序号是上次已成功收到数据字节序号加1。只有ACK标志为1时确认序号字段才有效。

发送ACK无需任何代价,因为32bit的确认序号字段和ACK标志一样,总是TCP首部的一部分。因此,一旦一个连接建立起来,这个字段总是被设置,ACK标志也总是被设置为1。

TCP为应用层提供全双工服务,这意味着数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。

TCP和UDP服务通常有一个客户/服务器的关系。例如,一个Telnet服务进程开始在系统上处于空闲状态,等待着连接。用户使用Telnet客户程序与服务进程建立一个连接。客户程序向服务进程写入信息,服务进程读出信息并发出响应,客户程序读出响应并向用户报告。因而,这个连接是双工的,可以用来进行读写。但是两个系统间的多重Telnet连接是如何相互确认并协调一致呢?TCP或UDP连接唯一地使用每个信息中的如下四项进行确认。

·源IP地址:发送包的IP地址。

·目的IP地址:接收包的IP地址。

·源端口:源系统上的连接端口。

·目的端口:目的系统上的连接端口。

端口是一个软件结构,被客户程序或服务进程用来发送和接收信息。一个端口对应一个16比特的数。服务进程通常使用一个固定的端口,例如,SMTP使用25。这些端口号是“广为人知”的,因为在建立与特定的主机或服务的连接时,需要这些地址和目的地址进行通信

TCP的数据报结构如下:

978-7-111-35607-3-Chapter09-64.jpg

由于单片微控制器的资源紧张,本设计没有实现分组与重组程序,在发送数据的时候每次只是发送一帧,发送成功之后,才去发送另外的一帧。这样就不需要分组与重组的程序。

1.状态转移图设计

TCP软件是以有限的状态机形式实现的。有限的状态机是一种状态转换机制,某时刻只能处在一个状态,它是通过事件来触发状态改变的。如果一个事件到来,状态机会根据现在所处的状态和事件的类型进入下一个状态。状态转移图是整个TCP软件设计的灵魂,将状态和作用于状态的事件相联系。在程序中设置了Tcp_Process函数,该函数在主程序中对tcp的状态进行转移,使它处理接收到的TCP数据,并作出相应的判断,跳入某种状态。为了便于说明,这里给出状态的转移图,如图9-20所示。

该状态转换模块使用的地方很多,一个到达的TCP报文段,一个超时事件,一个来自应用程序的报文等都可以用到该模块。这是一个非常复杂的模块,因为它要采取的动作取决于TCP的当前的状态和到来的事件。有很多的方法可以实现状态转换图,如每种状态使用一个进程或是数组等。它的设计可分为客户和服务器两个方面,限于篇幅,这里仅介绍服务器方面。虽然服务器可以处在11个状态之一,但是正常工作时,它只处于以下几个状态:CLOSED、LIS TEN、SYN_RCVD、ESTABLISED、CLOSE_WAIT和LAST_ACK。下面简要介绍如下:

1)服务器TCP在CLOSED状态开始。

2)在CLOSED状态时,服务器收到客户TCP连接请求,然后进入LISTEN状态。

3)在LISTEN状态时,服务器TCP能够收到客户TCP的SYN报文,它将SYN+ACK报文发送给客户TCP,然后进入SYN_RCVD状态。

978-7-111-35607-3-Chapter09-65.jpg

图9-20 TCP状态转移图

4)在SYN_RCVD状态时,服务器TCP接收到客户TCP的ACK报文,然后进入ES-TABLSED状态。这是个数据传送状态,只要服务器在发送和接收数据,它就继续在这个状态。(www.chuimin.cn)

5)在ESTABLSED状态时,服务器收到来自客户的FIN报文,表示客户愿意关闭这个连接,它可以发送ACK报文给客户,并进入CLOSE_WAIT状态。

6)在CLOSE_WAIT状态时,服务器TCP可以一直等待,直到收到来自服务器程序的关闭请求,这时发送FIN报文给客户,并进入LAST_ACK状态。

7)在LAST_ACK状态时,服务器就等待客户的ACK报文,然后进入CLOSED状态。

在程序中,使用case语句来处理状态。设计中将TCP的状态作了简化,只保留了6个主要的状态,并且每隔一秒进行超时处理。实践证明是可以建立可靠的TCP连接的。程序如下:

978-7-111-35607-3-Chapter09-66.jpg

978-7-111-35607-3-Chapter09-67.jpg

由于TCP协议是运输层最复杂的协议,在连接传输的过程中,有多个状态和多个参数,所以定义一个如下的数据结构:

978-7-111-35607-3-Chapter09-68.jpg

其中,连接状态(State)表示当前TCP所处的状态。

TCP的主要的函数为状态机函数,发送函数。状态机函数主要的功能为根据连接当前的状态和接收到的TCP报文,改变到下一状态,调用相应的处理函数。TCP发送函数主要是按照TCP报文的格式,生成报文并发送。

在程序中,使用单片微控制器的一个定时器作为系统的时钟,主要用于ARP的老化定时、各种超时定时等。IP协议采用统一的校验算法,其计算方法为:设校验和初值为0,然后对数据每16位求异或,结果取反,便得校验和。校验时将数据(含校验和)按同样的算法求和,结果为0表示数据正确;不为0则表示通信出错,需要丢弃该数据包。这样能简化校验程序设计,提高TCP/IP协议的效率。在编程的时候,只需要一个程序便可以了,不过需要注意的是TCP和UDP的校验需要加上伪头标,否则得不到正确的结果。伪头标违背了协议的分层原则,但这种违背是出于实际需要的,也正体现了TCP/IP协议设计的灵活性。

2.TCP头文件tcp.h

TCP头文件tcp.h定义如下:

978-7-111-35607-3-Chapter09-69.jpg

3.TCP程序设计

本程序在事件的驱动下,按照状态转移图进行TCP协议的处理。

TCP程序tcp.c设计如下:

978-7-111-35607-3-Chapter09-70.jpg

978-7-111-35607-3-Chapter09-71.jpg

978-7-111-35607-3-Chapter09-72.jpg

978-7-111-35607-3-Chapter09-73.jpg

978-7-111-35607-3-Chapter09-74.jpg

978-7-111-35607-3-Chapter09-75.jpg

978-7-111-35607-3-Chapter09-76.jpg

978-7-111-35607-3-Chapter09-77.jpg

978-7-111-35607-3-Chapter09-78.jpg

978-7-111-35607-3-Chapter09-79.jpg

978-7-111-35607-3-Chapter09-80.jpg

978-7-111-35607-3-Chapter09-81.jpg

978-7-111-35607-3-Chapter09-82.jpg