TCP: 传输控制协议
TCP状态流转图

TCP报文格式

为什么在TIME-WAIT状态必须等待2MSL时间呢?
- MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
- 2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。
- TTL与MSL是有关系的但不是简单的相等的关系,MSL要大于等于TTL。
- ip头中有一个TTL域,TTL是time to live的缩写,中文可以译为“生存时间”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。
- 如果Client(客户端)直接CLOSED(关闭),然后又再向Server(服务器端)发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。
迭代服务器与并发服务器
- 大多数TCP服务器是并发的,大多数UDP服务器是迭代的。
- 如果服务一个客户请求的时间不长,使用迭代服务器没有太大问题,一旦客户请求的时间需要花费很长,不希望整个服务器被单个客户长期占用,而希望同事服务多个客户,就需要选择并发服务器了。
int listenfd,connfd;
listenfd = socket( ... );
bind(listen, ... );
listen(listenfd,LISTENQ);
for(;;)
{
connfd = accept(listenfd, ... );
doit(connfd);
close(connfd);
}
int listenfd,connfd;
listenfd = socket( ... );
bind(listen, ... );
listen(listenfd,LISTENQ);
for(;;)
{
connfd = accept(listenfd, ... );
doit(connfd);
close(connfd);
}
用户数据报协议和IP分片
关于UDP,什么叫做无连接?什么是面向连接?
- 无连接:服务器处理完客户的请求,并收到客户的应答后,即断开连接。
HTTP
静态网页和动态网页
- 无状态是指服务器不知道客户端是什么状态。
- HTTP是一个无状态协议,这意味着每个请求都是独立的,Keep-Alive没能改变这个结果。
- 然而,随着时间的推移,人们发现静态的HTML着实无聊而乏味,增加动态生成的内容才会令Web应用程序变得更加有用。于是乎,HTML的语法在不断膨胀,其中最重要的是增加了表单(Form);客户端也增加了诸如脚本处理、DOM处理等功能;对于服务器,则相应的出现了CGI(Common Gateway Interface)以处理包含表单提交在内的动态请求。
- 在这种客户端与服务器进行动态交互的Web应用程序出现之后,HTTP无状态的特性严重阻碍了这些交互式应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,两种用于保持HTTP状态的技术就应运而生了,一个是Cookie,而另一个则是Session。