tcp协议与 udp协议的区别

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

TCP 与UDP的区别
很多文章都说TCP协议可靠,UDP协议不可靠!为什么前者可靠,后者不可靠呢?既然UDP协议不可靠,为什么还要使用它呢?所谓的TCP协议是面向连接的协议,面向连接是什么呢?
TCP和UDP都是传输层的协议!从编程的角度看,就是两个模块(模块就是代码的集合,一系列代码的组合提供相应的功能!模块化最终目的就是:分工协作!模块化好处:便于扩展开发以及维护!)。

先说TCP协议:
这个协议,是面向的连接!面向连接这个概念,我们要从物理层看起。

大家都知道,因为“信道复用技术”的迅猛发展,才促使了计算机网络的发展!如果没有“信道复用技术”,那么单条线路上(这里的线路指物理传输介质,例如:双绞线、光纤、电话线)单位时间内只能供一台计算机使用!还是举例说明:就拿你自己的计算机来说,你跟同学“小明”聊天的时候,就不能跟另外一位同学“小强”聊天,如果你想同时跟两位同学聊天,那么你就得装两条线路!那么同时与第三位、第四位同学。

第N位同学聊天的时候,你需要装几根线路?全世界人民聊天的时候,又需要装几根线路?
“信道复用技术”实现了,在同一条线路上,单位时间内可供X台计算机同时通信!Toad知道以下几种复用技术:
1、频分复用
2、时分复用
3、波分复用
4、码分复用
5、空分复用
6、统计复用
7、极化波复用
关于“信道复用技术”更深层次的问题,需要你自己去研究!
上面我们提到了“信道复用技术”!知道了这一点,我们就很容易明白“物理信道”上的“虚拟信道”概念了!不同的信道复用技术,使用不同的复用技术,目的就是创建“虚拟信道”。

一个TCP协议连接其实就是在物理线路上创建的一条“虚拟信道”。

这条“虚拟信道”建立后,在TCP协议发出FIN包之前(两个终端都会向对方发送一个FIN包),是不会释放的。

正因为这一点,TCP协议被称为面向连接的协议!
UDP协议,一样会在物理线路上创建一条“虚拟信道”,否则UDP协议无法传输数据!但是,当UDP协议传完数据后,这条“虚拟信道”就被立即注销了!因此,称UDP是不面向连接的协议!
大家要知道,一种物理线路,单位时间内,能够创建的“虚拟信道”是有限的!从这个问题,大家应该明白了TCP协议和UDP协议为什么会共存了吧,然而,这只是其中一个原因而已!
那为什么又说TCP协议可靠,UDP协议不可靠呢?以上说的是一个原因,还有一个原因是:使用TCP协议传输数据,当数据从A端传到B端后,B端会发送一个确认包(ACK包)给A端,告知A端数据我已收到!UDP协议就没有这种确认机制!这一点,在做TCP协议首部分析时,会详加解释!
QQ普通会员就是使用的UDP协议进行传输数据!既然UDP协议自身没有确认机制,这个工作可以交给应用层的进程来完成(QQ)!大家使用QQ的时候,感觉出错的几率还是非常小吧!当然,把这个确认工作完全交给QQ自身来做,就直接导致了,QQ软件体积增大!
有些应用,对数据传输可靠性要求非常高,例如大家浏览网页,通过网页注册帐号、转帐等服务,这是不容许出错的,使用TCP协议能把出错的可能性降到最低(当然,网络自身很糟糕,TCP协议也没办法)。

但是,提供这种可靠服务,会加大网络带宽的开销,因为“虚拟信道”是持续存在的,同时网络中还会出现大量的ACK和FIN包!
因此,鱼和熊掌不可兼得,需根据实际情况选择传输协议
TCP协议提供了可靠的数据传输,但是其拥塞控制、数据校验、重传机制的网络开销很大,不适合实时通信,所以选择开销很小的UDP协议来传输数据。

UDP 协议是无连接的数据传输协议并且无重传机制,会发生丢包、收到重复包、乱序等情况。

而对于数据精确性要求不高的状态数据以及视频数据,丢包的影响不大。

因为会不断收到新的包,丢失的个别包会有新的包来覆盖,所以只需在远程控制系统的通信部分自行处理乱序及重复包的问题,而对于丢包的问题一般不作处理。

但对于命令包这种需要精确收发的数据, 可在程序的开发中加入丢包重发和超时丢弃的处理。

当然,如果开发的是对于实时性要求不高的事件型控制命令的传输,不希望发生指令的丢失也可以直接采用TCP协议。

TCP的重传机制正好适合这种情况。

非面向连接的传输协议在数据传输之前不建立连接,而是在每个中间节点对非面向连接的包和数据包进行路由。

没有点到点的连接,非面向连接的协议,如UDP,是不可靠的连接。

当一个UDP数据包在网络中移动时,发送过程并不知道它是否到达了目的地,除非应用层已经确认了它已到达的事实。

非面向连接的协议也不能探测重复的和乱序的包。

标准的专业术语用“不可靠”来描述UDP。

在现代网络中,UDP并不易于导致传输失败,但是你也不能肯定地说它是可靠的。

UDP
User Datagram Protocol
用户数据报协议
UDP是ISO参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

UDP 协议基本上是IP协议与上层协议的接口。

UDP协议适用端口分辨运行在同一台设备上的多个应用程序。

目录
• 1 简介
• 2 为什么要使用UDP?
• 3 UDP报头
• 4 UDP协议的几个特性
• 5 UDP vs TCP
• 6 UDP协议的应用
•7 UDP 程序设计
UDP-简介
UDP协议的全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包。

在OSI 模型中,在第四层——传输层,处于IP协议的上一层。

UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

UDP用来支持那些需要在计算机之间传输数据的网络应用。

包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。

UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天,UDP仍然不失为一项非常实用和可行的网络传输层协议。

与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。

根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。

UDP协议的主要作用是将网络数据流量压缩成数据报的形式。

一个典型的数据报就是一个二进制数据的传输单位。

每一个数据报的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

UDP-为什么要使用UDP?
在选择使用协议的时候,选择UDP必须要谨慎。

在网络质量令人不十分满意的环境下,UDP 协议数据包丢失会比较严重。

但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。

比如我们聊天用的ICQ和OICQ就是使用的UDP协议。

UDP-UDP报头
UDP
UDP报头由4个域组成,其中每个域各占用2个字节,具体如下:
UDP
源端口号
目标端口号
数据报长度
校验值
UDP协议使用端口号为不同的应用保留其各自的数据传输通道。

UDP和TCP协议正是采用这一机制实现对同一时刻内多项应用同时发送和接收数据的支持。

数据发送一方(可以是客户端或服务器端)将UDP数据报通过源端口发送出去,而数据接收一方则通过目标端口接收数据。

有的网络应用只能使用预先为其预留或注册的静态端口;而另外一些网络应用则可以使用未被注册的动态端口。

因为UDP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。

一般来说,大于49151的端口号都代表动态端口。

数据报的长度是指包括报头和数据部分在内的总字节数。

因为报头的长度是固定的,所以该域主要被用来计算可变长度的数据部分(又称为数据负载)。

数据报的最大长度根据操作环境的不同而各异。

从理论上说,包含报头在内的数据报的最大长度为65535字节。

不过,一些实际应用往往会限制数据报的大小,有时会降低到8192字节。

UDP协议使用报头中的校验值来保证数据的安全。

校验值首先在数据发送方通过特殊的算
法计算得出,在传递到接收方之后,还需要再重新计算。

如果某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检测是否出错。

这与TCP协议是不同的,后者要求必须具有校验值。

检查和的详细计算可在RFC1071中找到,现举一例说明使用检查和检测错误的道理。

例如,假设从源端A要发送下列3个16位的二进制数:word1,word2和word3到终端B,检查和计算如下:
从发送端发出的4个(word1,2,3以及检查和)16位二进制数之和为1111111111111111,如果接收端收到的这4个16位二进制数之和也是全“1”,就认为传输过程中没有出差错。

许多链路层协议都提供错误检查,包括流行的以太网协议,也许想知道为什么UDP也要提供检查和。

其原因是链路层以下的协议在源端和终端之间的某些通道可能不提供错误检测。

虽然UDP提供有错误检测,但检测到错误时,UDP不做错误校正,只是简单地把损坏的消息段扔掉,或者给应用程序提供警告信息。

UDP-UDP协议的几个特性
(1) UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。

在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP 把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

(2) 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

(3) UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

(4) 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

虽然UDP是一个不可靠的协议,但它是分发信息的一个理想协议。

例如,在屏幕上报告股票市场、在屏幕上显示航空信息等等。

UDP也用在路由信息协议RIP(Routing Information Protocol)中修改路由表。

在这些应用场合下,如果有一个消息丢失,在几秒之后另一个新的消息就会替换它。

UDP广泛用在多媒体应用中,例如,Progressive Networks公司开发的RealAudio软件,它是在因特网上把预先录制的或者现场音乐实时传送给客户机的一种软件,该软件使用的RealAudio audio-on-demand protocol协议就是运行在UDP之上的协议,大多数因特网电话软件产品也都运行在UDP之上。

UDP-UDP vs TCP
UDP
UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同。

TCP协议中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时,会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。

UDP
与TCP不同,UDP协议并不提供数据传送的保证机制。

如果在从发送方到接收方的传递过程中出现数据报的丢失,协议本身并不能做出任何检测或提示。

因此,通常人们把UDP协议称为不可靠的传输协议。

相对于TCP协议,UDP协议的另外一个不同之处在于如何接收突法性的多个数据报。

不同于TCP,UDP并不能确保数据的发送和接收顺序。

例如,一个位于客户端的应用程序向服务器发出了以下4个数据报
D1
D22
D333
D4444
但是UDP有可能按照以下顺序将所接收的数据提交到服务端的应用:
D333
D1
D4444
D22
事实上,UDP协议的这种乱序性基本上很少出现,通常只会在网络非常拥挤的情况下才有可能发生。

UDP-UDP协议的应用
既然UDP是一种不可靠的网络协议,那么还有什么使用价值或必要呢?其实不然,在有些
情况下UDP协议可能会变得非常有用。

因为UDP具有TCP所望尘莫及的速度优势。

虽然TCP协议中植入了各种安全保障功能,但是在实际执行的过程中会占用大量的系统开销,无疑使速度受到严重的影响。

反观UDP由于排除了信息可靠传递机制,将安全和排序等功能移交给上层应用来完成,极大降低了执行时间,使速度得到了保证。

关于UDP协议的最早规范是RFC768,1980年发布。

尽管时间已经很长,但是UDP协议仍然继续在主流应用中发挥着作用。

包括视频电话会议系统在内的许多应用都证明了UDP协议的存在价值。

因为相对于可靠性来说,这些应用更加注重实际性能,所以为了获得更好的使用效果(例如,更高的画面帧刷新速率)往往可以牺牲一定的可靠性(例如,会面质量)。

这就是UDP和TCP两种协议的权衡之处。

根据不同的环境和特点,两种传输协议都将在今后的网络世界中发挥更加重要的作用。

UDP-UDP 程序设计
UDP Server程序
1、编写UDP Server程序的步骤
(1)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。

(2)初始化sockaddr_in结构的变量,并赋值。

sockaddr_in结构定义:
struct sockaddr_in {
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
这里使用“08”作为服务程序的端口,使用“INADDR_ANY”作为绑定的IP地址即任何主机上的地址。

(3)使用bind()把上面的socket和定义的IP地址和端口绑定。

这里检查bind()是否执行成功,如果有错误就退出。

这样可以防止服务程序重复运行的问题。

(4)进入无限循环程序,使用recvfrom()进入等待状态,直到接收到客户程序发送的数据,就处理收到的数据,并向客户程序发送反馈。

这里是直接把收到的数据发回给客户程序。

2、udpserv.c程序内容:
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8888
void do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)
{
int n;
socklen_t len;
char mesg[MAXLINE];
for(;;)
{
len = clilen;
/* waiting for receive data */
n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
/* sent data back to client */
sendto(sockfd, mesg, n, 0, pcliaddr, len);
}
}
int main(void)
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
/* bind address and port to socket */
if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
{
perror("bind error");
exit(1);
}
do_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
return 0;
}
UDP Client程序
1、编写UDP Client程序的步骤
(1)初始化sockaddr_in结构的变量,并赋值。

这里使用“8888”作为连接的服务程序的端口,从命令行参数读取IP地址,并且判断IP地址是否符合要求。

(2)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。

(3)使用connect()来建立与服务程序的连接。

与TCP协议不同,UDP的connect()并没有与服务程序三次握手。

上面说了UDP是非连接的,实际上也可以是连接的。

使用连接的UDP,kernel可以直接返回错误信息给用户程序,从而避免由于没有接收到数据而导致调用recvfrom()一直等待下去,看上去好像客户程序没有反应一样。

(4)向服务程序发送数据,因为使用连接的UDP,所以使用write()来替代sendto()。

这里的数据直接从标准输入读取用户输入。

(5)接收服务程序发回的数据,同样使用read()来替代recvfrom()。

(6)处理接收到的数据,这里是直接输出到标准输出上。

udpclient.c程序内容:
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8888
void do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen) {
int n;
char sendline[MAXLINE], recvline[MAXLINE + 1];
/* connect to server */
if(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)
{
perror("connect error");
exit(1);
}
while(fgets(sendline, MAXLINE, fp) != NULL)
{
/* read a line and send to server */
write(sockfd, sendline, strlen(sendline));
/* receive data from server */
n = read(sockfd, recvline, MAXLINE);
if(n == -1)
{
perror("read error");
exit(1);
}
recvline[n] = 0; /* terminate string */
fputs(recvline, stdout);
}
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in srvaddr;
/* check args */
if(argc != 2)
{
printf("usage: udpclient \n");
exit(1);
}
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
printf("[%s] is not a valid IPaddress\n", argv[1]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
do_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
return 0;
}
运行例子程序
1、编译例子程序
使用如下命令来编译例子程序:
gcc -Wall -o udpserv udpserv.c
gcc -Wall -o udpclient udpclient.c
编译完成生成了udpserv和udpclient两个可执行程序。

2、运行UDP Server程序
执行./udpserv &命令来启动服务程序。

我们可以使用netstat -ln命令来观察服务程序绑定的IP地址和端口,部分输出信息如下:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:32768 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
udp 0 0 0.0.0.0:32768 0.0.0.0:*
udp 0 0 0.0.0.0:8888 0.0.0.0:*
udp 0 0 0.0.0.0:111 0.0.0.0:*
udp 0 0 0.0.0.0:882 0.0.0.0:*
可以看到udp处有“0.0.0.0:8888”的内容,说明服务程序已经正常运行,可以接收主机上任何IP地址且端口为8888的数据。

如果这时再执行./udpserv &命令,就会看到如下信息:
bind error: Address already in use
说明已经有一个服务程序在运行了。

运行UDP Client程序
执行./udpclient 127.0.0.1命令来启动客户程序,使用127.0.0.1来连接服务程序,执行效果如下:
Hello, World!
Hello, World!
this is a test
this is a test
^d
输入的数据都正确从服务程序返回了,按ctrl+d可以结束输入,退出程序。

如果服务程序没有启动,而执行客户程序,就会看到如下信息:
$ ./udpclient 127.0.0.1
test
read error: Connection refused
说明指定的IP地址和端口没有服务程序绑定,客户程序就退出了。

这就是使用connect()的好处,注意,这里错误信息是在向服务程序发送数据后收到的,而不是在调用connect()时。

如果使用tcpdump程序来抓包,会发现收到的是ICMP的错误信息。

TCP
目录
• 1 传输控制协议
• 2 运作方式
o 2.1 通路的建立和终结
o 2.2 数据传输
o 2.3 通路的终结
• 3 TCP的端口
• 4 TCP的封包结构
• 5 TCP的发展过程
• 6 对TCP的选用情况
TCP-传输控制协议
传输控制协议(Transmission Control Protocol, TCP)是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议,由IETF的RFC 793说明(specified)。

在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,UDP是同一层内另一个重要的传输协议。

在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。

不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分割成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)的限制)。

之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。

TCP 为了保证不发生丢包,就给每个字节一个序号,同时序号也保证了传送到接收端实体的包的按序接收。

然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。

TCP 用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

TCP-运作方式
通路的建立和终结
TCP连接包括三个状态:连接建立、数据传送和连接终止。

TCP用三路握手(three-way handshake)过程建立一个连接,用四路握手(four-way handshake)过程来拆除一个连接。

在连接建立过
tcp建立连接
程中,很多参数要被初始化,例如序号被初始化以保证按序传输和连接的强壮性。

TCP连接的正常建立一对终端同时初始化一个它们之间的连接是可能的。

但通常是由一端打开一个接口(socket)然后监听来自另一方的连接,这就是通常所指的被动打开(passive open)。

服务器端被被动打开以后,用户端就能开始建立主动打开(active open)。

1.客户端通过向服务器端发送一个SYN来建立一个主动打开,作为三路握手的一部分。

2.服务器端应当为一个合法的SYN回送一个SYN/ACK。

3.最后,客户端再发送一个ACK。

这样就完成了三路握手,并进入了连接建立状态。

数据传输
在TCP的数据传送状态,很多重要的机制保证了TCP的可靠性和强壮性。

它们包括:使用序号,对收到的TCP报文段进行排序以及检测重复的数据;使用校验和来检测报文段的错误;使用确认和计时器来检测和纠正丢包或延时。

序列号和确认
在TCP的连接建立状态,两个主机的TCP层间要交换初始序号(ISN:initial sequence number)。

这些序号用于标识字节流中的数据,并且还是对应用层的数据字节进行记数的整数。

通常在每个TCP报文段中都有一对序号和确认号。

TCP报文发送者认为自己的字节编号为序号,而认为接收者的字节编号为确认号。

TCP报文的接收者为了确保可靠性,在接收到一定数量的连续字节流后才发送确认。

这是对TCP的一种扩展,通常称为选择确认(Selective Acknowledgement)。

选择确认使得TCP接收者可以对乱序到达的数据块进行确认。

每一个字节传输过后,ISN号都会递增1。

通过使用序号和确认号,TCP层可以把收到的报文段中的字节按正确的顺序交付给应用层。

序号是32位的无符号数,在它增大到232-1时,便会回绕到0。

对于ISN的选择是TCP中关键的一个操作,它可以确保强壮性和安全性。

数据传输举例
1.发送方首先发送第一个包含序列号为1(可变化)和1460字节数据的TCP报文段给接收方。

接收方以一个没有数据的TCP报文段来回复(只含报头),用确认号1461来表示已完全收到并请求下
TCP数据传输
一个报文段。

2.发送方然后发送第二个包含序列号为1461和1460字节数据的TCP报文段给接收方。

正常情况下,接收方以一个没有数据的TCP报文段来回复,用确认号2921(1461+1460)来表示已完全收到并请求下一个报文段。

发送接收这样继续下去。

3.然而当这些数据包都是相连的情况下,接收方没有必要每一次都回应。

比如,他收到第1到5条TCP报文段,只需回应第五条就行了。

在例子中第3条TCP报文段被丢失了,所以尽管他收到了第4和5条,然而他只能回应第2条。

4.发送方在发送了第三条以后,没能收到回应,因此当时钟(timer)过时(expire)时,他重发第三条。

(每次发送者发送一条TCP报文段后,都会重启动一次时钟:RTT)。

5.这次第三条被成功接收,接收方可以直接确认第5条,因为4,5两条已收到。

校验和
TCP的16位的校验和(checksum)的计算和检验过程如下:发送者将TCP报文段的头部和数据部分的和计算出来,再对其求反码(一的补数),就得到了校验和,然后将结果装入报文中传输。

(这里用反码和的原因是这种方法的循环进位使校验和可以在16位、32位、64位等情况下的计算结果在叠加后相同)接收者在收到报文后再按相同的算法计算一次校验和。

这里使用的反码使得接收者不用再将校验和字段保存起来后清零,而可以直接将报文段连同校验加总。

如果计算结果是全部为一,那么就表示了报文的完整性和正确性。

注意:TCP校验和也包括了96位的伪头部,其中有源地址、目的地址、协议以及TCP的长度。

这可以避免报文被错误地路由。

按现在的标准,TCP的校验和是一个比较脆弱的校验。

具有高出错率的数据链路层需要额外的连接错误纠正和探测能力。

如果TCP是在今天被设计,它很可能有一个32位的CRC 校验来纠错,而不是使用校验和。

但是通过在第二层使用通常的CRC或更完全一点的校验可以部分地弥补这种脆弱的校验。

第二层是在TCP层和IP层之下的,比如PPP或以太网,它们使用了这些校验。

但是这也并不意味着TCP的16位校验和是冗余的,对于因特网传输的观察,表明在受CRC保护的各跳之间,软件和硬件的错误通常也会在报文中引入错误,而端到端的TCP校验能够捕捉到很多的这种错误。

这就是应用中的端到端原则。

流量控制和阻塞管理
数据发送者之间用对接收数据的确认或不予确认来显式的表示TCP发送者和接收者之间的网络状态。

再加上计时器,TCP发送者和接收者就可以改变数据的流动情况。

这就是通常所指的流量控制(Flow control),拥塞控制/或拥塞避免。

TCP使用大量的机制来同时获得强壮性和高可靠性。

这些机制包括:滑动窗口、慢启动算法、拥塞避免算法、快速重启和快速。

相关文档
最新文档