博主将会针对Java面试题写一组文章,包括J2ee,SQL,主流Web框架,中间件等面试过程中面试官经常问的问题,欢迎大家关注。一起学习,一起成长。

一、TCP报文图:

1.源端口-目的端口:在程序中两个进程可以用PID来唯一标识,而在网络中如若靠IP+线程PID来确认数据来源,可能会出现两台计算机PID一致的情况,所以为了解决这个问题,传输层引入了协议版本号port,简称端口,这样子就能通过ip地址+协议+端口号来唯一标识网络中的进程,也成为套接字,socket。

2.序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。

3.确认号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。

4.标志位TCPFlag:当如下标志位等于1时有效,等于0时无效。重点关注ACK,SYN,FIN。

(A)URG:紧急指针(urgent pointer)有效。(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。

5.窗口:发送端接收端的的缓存大小,以此控制发送端发送数据的速率,达到控制流量的效果。

注意:不要将确认序号ack与标志位中的ACK搞混了,确认方ack=发起方seq+1,两端配对。 而大写的ACK=1表示的是需要对小写ack序号确认的标志。

二、TCP三次握手

(1)第一次握手:Server最初处于Listen状态,Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

三、建立的过程服务器发送的最后一个报文,客户端挂了会怎样?(SYN超时)

Server收到Client的SYN,回复SYN+ACK时候未收到客户端的ACK;(如此时客户端忽然断电,断网等特殊情况) 此时,在Linux下,Server会不断重试SYN+ACK报文,一共会重试5次,分别间隔1,2,4,8,16,32秒。等待63s后仍然未回应,默认断开连接。

四、SYN攻击:

漏洞原因:
在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。

SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:
#netstat -nap | grep SYN_RECV

解决:

①当安全设备获取到发往服务器的SYN报文后,设备模拟服务器给源IP回复seq=Cookie的SYN+ACK报文。(通过SYN cookies 五元组加密算法来计算cookie的值,包括时间戳,长度,缩放银子等综合计算得出)

②正常客户端会回复ACK报文,确认序列号为ack=cookie+1。

③安全设备收到ack报文后,将ack - 1就可以拿回当初发送的SYN+ACK报文中的cookie值序号了!服务器巧妙地通过这种方式间接保存了一部分SYN报文的信息,再根据连接信息元组重新计算s,看是否和低 24 一致,若不一致,说明这个报文是被伪造的。

五、为什么TCP要三次握手才能建立连接?

为了初始化sequence-number的值。通知双方,作为以后数据的传输序号,每次传输+1,tcp会根据这个序号来拼接数据,以免扰乱了数据的顺序。

六、建立连接后Client出现故障怎么办?

保活机制。在一段时间,称为保活时间KeepLineTime,服务端处于非活跃状态,将会陆续发送保活探测报文,直到达到保活探测报文的最高次数。