TCP数据发送之发送窗口

TCP的发送过程由滑动窗口控制,而滑动窗口的大小受限于发送窗口和拥塞窗口,拥塞窗口由拥塞控制算法的代表,而发送窗口是流量控制算法的代表,这篇笔记记录了发送窗口相关的内容,包括发送窗口的初始化、更新、以及它是如何影响数据发送过程的。

1. 概述

TCP的发送窗口可以用下图表示:
在这里插入图片描述

如图所示,TCB中有三个成员和发送窗口强相关。

struct tcp_sock {
   
...
	//下一个要发送的序号,即序号等于snd_nxt的数据还没有发送
	u32	snd_nxt;	/* Next sequence we send		*/
	//已经发送,但是还没有被确认的最小序号,注意序号等于snd_una的数据已经发送,
	//最想收到的确认号要大于snd_una。但是有一个特殊情况,如果发送的所有数据都
	//已经被确认,那么snd_una将等于下一个要发送的数据,即snd_una代表的数据还
	//没有发送,见下面tcp_ack()更新snd_una就可以理解这一点了
	u32	snd_una;	/* First byte we want an ack for	*/
	//发送窗口大小,以字节为单位,来源于输入段首部的窗口字段,即对端接收缓冲区的剩余大小
	u32	snd_wnd;	/* The window we expect to receive	*/
	//记录到目前为止对端通告过的窗口的最大值,可以代表对端接收缓冲区的最大值
	u32	max_window;	/* Maximal window ever seen from peer	*/
	//写系统调用一旦成功返回,说明数据一被TCP协议接收,这时就要为每一个数据分配一个序号,
	//write_seq就是下一个要分配的序号,其初始值由secure_tcp_sequence_number()基于
	//算法生成。注意等于write_seq的序号还没有被分配
	u32	write_seq;	/* Tail(+1) of data held in tcp send buffer */
...
};

2. snd_una和snd_wnd的更新

snd_una是发送窗口的左边界,如果该字段更新,即使发送窗口大小snd_wnd没有发生变化,整个发送窗口也会前移,这样从流量控制的角度,就可以发送更多的数据(是否真的可以发送,还要考虑拥塞窗口等其它因素)。

2.1 初始化

可以想的到,snd_una的初始化一定发生在第一个数据段发送过程中,而snd_wnd的初始化应该是发生在第一个输入段处理过程中,所以需要客户端和服务器端分开来看。

2.1.1 客户端初始化

客户端对snd_una的初始化当然是发生在SYN段的发送过程中,相关代码如下:

int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
   
...
	//选择初始发送序号
	if (!tp->write_seq)
		tp->write_seq = secure_tcp_sequence_number(inet->saddr,
							   inet->daddr,
							   inet->sport,
							   usin->sin_port);
...
}
static void tcp_connect_init(struct sock *sk)
{
   
...
	//发送窗口大小要从输入段首部的窗口字段获取,这时还没有任何输入段,先初始化为0
  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值