已经收到了数据。
发送者保存发送的数据的记录, 在发送下一个数据之前, 等待这个数据的确认消息。
在它发送这个数据的同时, 还启动了一个记时器。如果在一定时间之内, 没有接收到确认
消息, 就认为是这个数据在传送时丢失了, 接着, 就会重新发送这个数据。
这种方法还产生了一个问题, 就是包的重复。如果网络传输速度比较低, 等到等待时
间结束后, 确认消息才返回到发送者, 那么, 由于发送者采用的发送方法, 就会出现重复的
数据了。解决的一个办法是给每个数据一个序列号, 并需要发送者记住哪个序列号的数
据已经确认了。为了防止由于延时或重复确认, 规定确认消息里也要包含确认序列号。
从而发送者就能知道哪个包已经确认了。TCP 协议中还有一个重要的概念: 滑动窗口。
这一方法的使用, 使得传输更加高效。
从前面的描述可见, 发送者在发送完一个数据包之后, 要等待确认。在它收到确认消
息之前的这段时间是空闲的。如果网络延时比较长, 这个问题会相当明显。
滑动窗口方法是在它收到确认消息以前, 发送多个数据包。可以想象成有一个窗口
在一个序列上移动。
如果一个包发送出去之后还没有确认, 叫做未确认包。通常未确认的包的个数就是
窗口的大小。
此窗口的大小为8。发送者允许在接收到一个确认消息以前发送8 个数据包。当发
送者接到窗口中第一个包的确认消息时, 它就将窗口下滑一个。
在接收端, 也有一个滑动窗口接收和确认一个包。
使用TCP 传输就是建立一个连接。在TCP 传输中一个连接由两个端点组成。其
实, 一个连接代表的是发送和接收两端应用程序之间的一个通信。可以把它们想象成建
立了一个电路。通常一个连接用下面的公式表示:
( host , port )
host 是主机, por t 是端口。TCP 端口能被几个应用程序共享。对于程序员来讲, 可以
这样理解: 一个应用程序可以为不同的连接提供服务。
TCP 传输的单位是段, 在建立连接, 传送数据, 确认消息和告知窗口大小时均要进行
段的交换。
段的格式也分成两部分: 头和数据。
上面格式中的名称已经足够说明它们的作用了。具体的含义请参见有关资料。
TCP 协议使用一个三次握手来建立一个TCP 连接的。
握手过程的第一个段的代码位设置为SYN, 序列号为x , 表示开始一次握手。接收方
收到这个段后, 向发送者回发一个段。代码位设置为SYN 和ACK, 序列号设置为y , 确认
序列号设置为x + 1。发送者在收到这个段后, 知道就可以进行TCP 数据发送了, 于是,
它又向接收者发送一个ACK 段, 表示, 双方的连接已经建立。
在完成握手之后, 就开始正式的数据传输了。上面握手中的序列号都是随机产生的。
4 .3 .7 Linux 网络编程(Berkeley Sockets)