位置:51电子网 » 技术资料 » 嵌入式系统

TOP数据传输实现的软件设计中注意的事项

发布时间:2008/12/30 0:00:00 访问次数:408

  (1)tcb

  tcp模块中有一个tcb(传输控制模块,transmit control block),它用于记录tcp协议运行过程中的 变量。对于有多个连接的tcp,每个连接都有一个tcb,这里只有一个。tcb结构的定义包括这个连接使用 的源端口、目的端口、目的ip、序号、应答序号、对方窗口大小、己方窗口大小、tcp状态、top输入/输出队列、应用层输出队列、tcp的重传有关变量。

  (2)rap状态转化(状态:能够对其产生影响的事件)

  在特定的rap状态下,相应的事件触发相应的动作和相应的状态转化。状态转化如下:

  (3)接收流程

  tcpin()进程是主接收流程。tcpin进程查看top输入队列中是否有元素,有则提取并从队列中删除。 然后看校验和是否正确,再看端口是否正确,调用tcpportok函数。tcpportok函数,首先看是否为syn包 ,对这种包都不加以拒绝,否则要求不在closed和listen状态,并且源目的端口和目的ip地址要正确才 接收。

  接着调用tcpexpectedpacket来看收到的这个包的序号是否是自己想要的序号,复杂的tcp协议只要序号 落在窗口范围内就接收,这里为了简便只允许接收特定序号的包。如果以上的检测都通过,则说明是一 个所希望的包。用新接收的包调用tcpreceiverenew函数来更新tcb的值,tcpreceiverenew函数主要用来 更新应答序号、释放重发队列中被应答的元素(以后说明),以及事件处理和状态转化。在

  处理中,有些状态要判断是否是对方发来的第一个包,如果是则要initial ack,即初始化acksequence ,对于establish状态还要判断是否发送应答包。

  接下来,如果这个包中含有数据则调用tcponreceive,用户在这个函数中处理接收。tcpin函数在最后 无论如何要释放这个包。

  (4)发送流程

  tcpout是发送主进程。首先它检测是否有top包要重发(以后说明),然后要求rap不处于closed, listen,synrecvd,synsent状态,这些状态不能发送数据。接着看重传队列是否很满,再看应用层输出 队列中是否有元素,有则用tcpsendpacket发送此包。

  tcpsendpacket函数负责发送一个top包。它首先判断page是否合法,因为很多地方使用tcpsendpacket (tcpallocatewithoutdata(),tcp_ack);的形式,所以可能tcpallocatewithoutdata没能分配到内存 ;page非法则退出,这里的非法退出可能导致协议失败,但是在内存够用的情况下不会发生。然后将包 写入重传队列,填写tcp头;接着更新sequence,填写ip头的目的ip,再写入tcp输出队列。

  (5)定时重发

  符合条件if(datasize!=0|| (tcpflag& (top_syn丨top_fin))!=0)的tcp需要重发。重发思路 如下:

  将所有发送的数据包都写入重发队列queueretransmit,其中包括需要重发的和不需要重发的tcp包,并 将tcp包的序号写入sequenceofretransmit,将是否需要重发标志写入flagofretransmit。如图1所示, 图中第二个序号为2100、3003的包是不需要重发的。


 图1 定时重传队列

  (6)窗口大小选择

  本地窗口固定为tcp_source_windows,这是为了避免tcp复杂的窗口算法。这里选择窗口大小一般比较 小。tcp只接收一个包,给予应答后才能接收另一个包,而一般的tcp都是一次发送多个的,如果对方发 来多个,这里只好抛弃,最好是对方不会一次发送多个。如果将窗口大小设得很小,则对方认为内存小 ,只连续发一个或很少。

  (7)如果给对方的应答包丢失

  比如发一个应答,希望对方发来序号为1000的包,但是这个包丢失,对方将不断地重发上一个包(例 如序号为900的包),则不断抛弃这个包(只接收一个指定序号为1000的包),协议出错。

  (8)应用层分包

  应用层定义的包和接收情况如图2所示


 图2 应用层定义的包和接收

  阴影部分表示新接收到的数据,即buff~buff+size内存区的内容。它是第1个包的末尾和第2个包的开 始。这就是说一次接收的不一定是一个完整的包,但是有时需要接收到一个完整的包时才能处理这个包 。这就是应用层分包问题,做法如下。

  从包的type字段可以知道这个类型的包大小为packettypetosize(type),所以应该接

  收packettypetosize(type)以后再处理这个包。接收完packettypetosize(type)个字节以后,下一 个一定是下一个包的type字段,然后又可以从packettypetosize(typo)得到需要接收的字节数。

  欢迎转载,信息来源维库电子市场网(www.dzsc.com)



  (1)tcb

  tcp模块中有一个tcb(传输控制模块,transmit control block),它用于记录tcp协议运行过程中的 变量。对于有多个连接的tcp,每个连接都有一个tcb,这里只有一个。tcb结构的定义包括这个连接使用 的源端口、目的端口、目的ip、序号、应答序号、对方窗口大小、己方窗口大小、tcp状态、top输入/输出队列、应用层输出队列、tcp的重传有关变量。

  (2)rap状态转化(状态:能够对其产生影响的事件)

  在特定的rap状态下,相应的事件触发相应的动作和相应的状态转化。状态转化如下:

  (3)接收流程

  tcpin()进程是主接收流程。tcpin进程查看top输入队列中是否有元素,有则提取并从队列中删除。 然后看校验和是否正确,再看端口是否正确,调用tcpportok函数。tcpportok函数,首先看是否为syn包 ,对这种包都不加以拒绝,否则要求不在closed和listen状态,并且源目的端口和目的ip地址要正确才 接收。

  接着调用tcpexpectedpacket来看收到的这个包的序号是否是自己想要的序号,复杂的tcp协议只要序号 落在窗口范围内就接收,这里为了简便只允许接收特定序号的包。如果以上的检测都通过,则说明是一 个所希望的包。用新接收的包调用tcpreceiverenew函数来更新tcb的值,tcpreceiverenew函数主要用来 更新应答序号、释放重发队列中被应答的元素(以后说明),以及事件处理和状态转化。在

  处理中,有些状态要判断是否是对方发来的第一个包,如果是则要initial ack,即初始化acksequence ,对于establish状态还要判断是否发送应答包。

  接下来,如果这个包中含有数据则调用tcponreceive,用户在这个函数中处理接收。tcpin函数在最后 无论如何要释放这个包。

  (4)发送流程

  tcpout是发送主进程。首先它检测是否有top包要重发(以后说明),然后要求rap不处于closed, listen,synrecvd,synsent状态,这些状态不能发送数据。接着看重传队列是否很满,再看应用层输出 队列中是否有元素,有则用tcpsendpacket发送此包。

  tcpsendpacket函数负责发送一个top包。它首先判断page是否合法,因为很多地方使用tcpsendpacket (tcpallocatewithoutdata(),tcp_ack);的形式,所以可能tcpallocatewithoutdata没能分配到内存 ;page非法则退出,这里的非法退出可能导致协议失败,但是在内存够用的情况下不会发生。然后将包 写入重传队列,填写tcp头;接着更新sequence,填写ip头的目的ip,再写入tcp输出队列。

  (5)定时重发

  符合条件if(datasize!=0|| (tcpflag& (top_syn丨top_fin))!=0)的tcp需要重发。重发思路 如下:

  将所有发送的数据包都写入重发队列queueretransmit,其中包括需要重发的和不需要重发的tcp包,并 将tcp包的序号写入sequenceofretransmit,将是否需要重发标志写入flagofretransmit。如图1所示, 图中第二个序号为2100、3003的包是不需要重发的。


 图1 定时重传队列

  (6)窗口大小选择

  本地窗口固定为tcp_source_windows,这是为了避免tcp复杂的窗口算法。这里选择窗口大小一般比较 小。tcp只接收一个包,给予应答后才能接收另一个包,而一般的tcp都是一次发送多个的,如果对方发 来多个,这里只好抛弃,最好是对方不会一次发送多个。如果将窗口大小设得很小,则对方认为内存小 ,只连续发一个或很少。

  (7)如果给对方的应答包丢失

  比如发一个应答,希望对方发来序号为1000的包,但是这个包丢失,对方将不断地重发上一个包(例 如序号为900的包),则不断抛弃这个包(只接收一个指定序号为1000的包),协议出错。

  (8)应用层分包

  应用层定义的包和接收情况如图2所示


 图2 应用层定义的包和接收

  阴影部分表示新接收到的数据,即buff~buff+size内存区的内容。它是第1个包的末尾和第2个包的开 始。这就是说一次接收的不一定是一个完整的包,但是有时需要接收到一个完整的包时才能处理这个包 。这就是应用层分包问题,做法如下。

  从包的type字段可以知道这个类型的包大小为packettypetosize(type),所以应该接

  收packettypetosize(type)以后再处理这个包。接收完packettypetosize(type)个字节以后,下一 个一定是下一个包的type字段,然后又可以从packettypetosize(typo)得到需要接收的字节数。

  欢迎转载,信息来源维库电子市场网(www.dzsc.com)



相关IC型号

热门点击

 

推荐技术资料

DFRobot—玩的就是
    如果说新车间的特点是“灵动”,FQPF12N60C那么... [详细]
版权所有:51dzw.COM
深圳服务热线:13751165337  13692101218
粤ICP备09112631号-6(miitbeian.gov.cn)
公网安备44030402000607
深圳市碧威特网络技术有限公司
付款方式


 复制成功!