1. 怎么实现强行关闭客户端和服务器之间的连接?
  2. TCP和UDP的区别

怎么实现强行关闭客户端和服务器之间的连接?

socket通信过程中不断循环检测一个全局变量(开关标记变量),一旦标记变量变为关闭,则 调用 socketclose 方法,循环结束,从而达到关闭连接的目的。

TCP和UDP的区别

TCP协议:是面向连接的通讯协议。通过三次握手建立连接,通讯完成时通过四次挥手断开

  • tcp协议的目的是为了保证数据能在两端准确连续的流动
  • 为了保证每个连接的独立性,tcp使用了socket数据结构来控制

优点:
1.tcp在数据传递时,有确认。窗口,重传,阻塞等控制机制,能够保证数据的正确性
2.
缺点:
1.TCP相对UDP速度慢一点,要求系统资源较多

UDP:面向无连接通讯,
优点:
1.UDP 速度快、操作简单、要求系统资源较少
2.由于通讯不需要连接,可以实现广播发送
缺点:
1.UDP 传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,也不重复发送,不可靠。

为什么说TCP是可靠的

1.应答确认: 客户端发送的每一个tcp报文段都必须得到接受方的应答,才认为这个tcp报文段传输成功
2.超时重传: 发送端在发出一个TCP报文段后启动定时器,如果在规定时间内未收到应答,将重新发送
3.数据确认: 因为TCP报文段最终是以IP数据报发送端,而IP数据报到达接收端可能乱序/重复,所以TCP协议还会对接收到的TCP报文段重排、整理再交付给应用层
4.窗口滑动: TCP头里有一个字段叫Window,又叫Advertised-Window,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据

三次握手

image.png

发送流程

1.客户端和服务端开启监听。等待对方发送消息
2.TCP客户端进程像服务端发送报文.携带SYN=1,同时选择一个初始化序列号seq=x。此时客户端A就进入了同步已发送状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。
3.TCP服务器收到请求报文后,如果同意连接,则发出确认报文,确认报文中应该ACK=1,SYN=1.确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。
4TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。
5.当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。

为什么最后还要发送一次
  • 主要为了防止已经失效的连接请求报文突然又传送到了服务器
    - 网络延迟
    - 导致的原因:
    - TCP的超时重传机制
    - 照成影响:
    - 导致服务端一直在等待,浪费服务端资源
    三次握手的作用
    1.使得通讯双方都做好了通讯的准备
    2.防止已经失效的链接请求报文段又突然传递到了服务端,从而产生错误
    三次握手哪个阶段容易出现攻击 / 异常
    1.第二阶段容易被攻击 / 异常,导致正常的客户端得不到响应而失败
    2.比较典型的是 syn 泛洪攻击,或叫 syn 溢出攻击。本质就是根据二次握手确定时间浪费服务器资源
    3listen 创建的监听队列达到上限,也可能失败。
    如果已经建立了连接,但是客户端突然出现故障了怎么办?
    TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

四次挥手

image.png
1.客户端进程发出连接释放报文,并且停止发送数据,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号
2.服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
3.客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据
4 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等

待客户端的确认。为什么连接的时候是三次握手,关闭的时候却是四次握手?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,”你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。