计算机网题目

计算机网题目

TCP 与 UDP 的区别

  • 1.连接 TCP 是面向连接的传输层协议,传输数据前先要建立连接。UDP 是不需要连接,即刻传输数据。

  • 2.服务对象 TCP 是一对一的两点服务,即一条连接只有两个端点。UDP 支持一对一、一对多、多对多的交互通信

  • 3.可靠性 TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按序到达。UDP 是尽最大努力交付,不保证可靠交付数据。

  • 4.拥塞控制、流量控制 TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率。

  • 5.首部开销 TCP 首部长度较长,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使用了「选项」字段则会变长的。UDP 首部只有 8 个字节,并且是固定不变的,开销较小。

  • 定义目录标题)

TCP 和 UDP应用场景:

  • 由于 TCP 是面向连接,能保证数据 的可靠性交付,因此经常用于:(20/21端口)FTP 文件传输、HTTP / HTTPS(80端口) 、SMTP(简单邮件传送协议)、TELNET(远程终端协议)
  • 由于 UDP 面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于:包总量较少的通信,如 DNS 、SNMP、TFTP(简单文件传输协议) 等、视频、音频等多媒体通信、广播通信

TCP 报文头部的格式

  • 序列号: 在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。

  • 确认应答号: 指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决不丢包的问题。

  • 控制位:

  • ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1 。

  • RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。

  • SYC:该位为 1 时,表示希望建立连,并在其「序列号」的字段进行序列号初始值的设定。

  • FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位置为 1 的 TCP 段。

请问TCP三次握手是怎样的?
  • 本地进程创建连接。即客户端A发生SYN (SYN=1,seq =x)报文给服务器B,然后进入SYN_SENT(同步已发送)状态。
  • 远程进程确认同时请求连接。即服务器B收到SYN报文后,回应一个SYN(seq =y) ACK(ack = x+1)报文,进入SYN_RCVD(同步收到)状态.
  • 本地进程确认。回应一个确认号ACK(ack=y+1),自己序号(seq=x+1),A进入established状态。B收到后也进入established状态。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e5cmPwKn-1619366662344)(…/index/tcp3-1.png)]
TCP 三次握手的原因
  • 三次握手才可以阻止重复历史连接的初始化(主要原因):一个「旧 SVN 报文」比「最新的 SYN 」 报文早到达了服务端,那么此时服务端就会回一个 SYN + ACK 报文给客户端;客户端收到后可以根据自身的上下文,判断这是一个历史连接(序列号过期或超时),那么客户端就会发送 RST 报文给服务端,表示中止这一次连接。如果是两次握手连接,就不能判断当前连接是否是历史连接,

  • 三次握手才可以同步双方的初始序列号 :序列号在 TCP 连接中占据着非常重要的作用,所以当客户端发送携带「初始序列号」的 SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的 SVN 报文已被服务端成功接收,那当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步。

  • 三次握手才可以避免资源浪费:即两次握手会造成消息滞留情况下,服务器重复接受无用的连接请求 SYN 报文,而造成重复分配资源。

为什么要传回SYN

  接收端传回发送端所发送的 SYN 是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。

传了SYN,为啥还要传ACK

  双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。

TCP握手为什么两次不可以?为什么不用四次?
  • 两次不可以:tcp是全双工通信,两次握手只能确定单向数据链路是可以通信的,并不能保证反向的通信正常。更精确的说法:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
  • 不用四次:四次握手其实也能够可靠的同步双方的初始化序号,但由于第二步和第三步可以优化成一步,为了加快握手效率,所以就成了「三次握手」。
如何在 Linux 系统中查看 TCP 状态?

  TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看。

为什么客户端和服务端的初始序列号 ISN 是不相同的?

  因为网络中的报文会延迟、会复制重发、也有可能丢失,这样会造成的不同连接之间产生互相影响,所以为了避免互相影响,客户端和服务端的初始序列号是随机且不同的。

初始序列号 ISN 是如何随机产生的?
  • 起始 ISN 是基于时钟的,每 4 毫秒 + 1,转一圈要 4.55 个小时。
  • RFC提出了初始化序列号 ISN 随机生成算法。 ISN = M + F M 是一个计时器 F 是一个 Hash 算法
SYN 攻击
  • 现象:我们都知道 TCP 连接建立是需要三次握手,假设攻击者短时间伪造不同 IP 地址的 SYN 报文,服务端每接收到一个 SYN 报文,就进入SYN_RCVD 状态,但服务端发送出去的 ACK + SYN 报文,无法得到未知 IP 主机的 ACK 应答,久而久之就会占满服务端的 SYN 接收队列(未连接队列),使得服务器不能为正常用户服务。
  • 避免SYN攻击:是通过修改 Linux 内核参数,控制队列大小和当队列满时应做什么处理。如设置SYN_RCVD 状态连接的最大个数。 超出处理能力时,对新的SYN直接回报RST,丢弃连接

TCP LAND攻击:

  • LAND攻击利用了TCP连接建立的三次握手过程,通过向一个目标主机发送一个用于建立请求连接的TCP SYN报文而实现对目标主机的攻击。与正常的TCP SYN报文不同的是:LAND攻击报文的源IP地址和目的IP地址是相同的,都是目标主机的IP地址。这样目标主机接在收到这个SYN 报文后,就会向该报文的源地址发送一个ACK报文,并建立一个TCP连接控制结构,而该报文的源地址就是自己。由于目的IP地址和源IP地址是相同的,都是目标主机的IP地址,因此这个ACK 报文就发给了目标主机本身。
  • TCP是面向连接的,经过三次握手后,所以TCP的源IP也可能是伪造的。对于UDP而言,不是面向连接的,所以源IP地址通常可以伪造的

TCP的三次握手是否可以携带数据

  • 第一次和第二次是不可以携带数据的,但是第三次是可以携带数据的。
  • 假如第一次握手可以携带数据的话,那对于服务器是不是太危险了,有人如果恶意攻击服务器,每次都在第一次握手中的SYN报文中放入大量数据。而且频繁重复发SYN报文,服务器会花费很多的时间和内存空间去接收这些报文。
  • 第三次握手,此时客户端已经处于ESTABLISHED状态。对于客户端来说,他已经建立起连接了,并且已经知道服务器的接收和发送能力是正常的。所以也就可以携带数据了。 ``

TCP连接释放

TCP四次挥手
  • (第一次):客户端进程发出连接释放报文,并且停止发送数据。发送FIN报文(FIN = 1),序列号为u(seq = u),客户端进入FIN-WAIT 1状态。
  • (第二次): 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,(客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)
  • (第三次):服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  • (第四次)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  • 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。
为什么挥手需要四次?
  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  • 服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
  • 从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次。
为什么 TIME_WAIT 等待的时间是 2MSL?
  • 原因 :保证最后一次握手报文能到B,能进行超时重传。比如最后服务器端没有收到断开连接最后的ACK报文,就会超时重发FIN报文,客户端接收到FIN后,会重发ACK给服务器端,一来一回正好使2MSL。并且2MSL后,这次连接的所有报文都会消失,不会影响下一次连接。
  • MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为 TCP 报文基于是 IP 协议的,而 IP 头中有一个 TTL 字段,是 IP 数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知源主机。
  • MSL 与 TTL 的区别: MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL 消耗为 0 的时间,以确保报文已被自然消亡。
为什么需要 TIME_WAIT 状态?
  • 经过 2MSL 这个时间,足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中都自然消失,再出现的数据包一定都是新建立连接所产生的。
  • 等待足够的时间以确保最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭。
TIME_WAIT 过多有什么危害?
  • 第一是内存资源占用;
  • 第二是对端口资源的占用,一个 TCP 连接至少消耗一个本地端口;

TIME_WAIT 太多该如何解决

  • https://blog.csdn.net/fanren224/article/details/89849276
  • 减小tw_buckets: tcp_max_tw_buckets = 256000 (内网低延迟等网络状况好的情况下可以设为0。网络状况不好的情况下设的过低有风险)
  • 减少时间: 修改linux内核减小MSL时间
  • 增大等待队列的长度: 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
如果已经建立了连接,但是客户端突然出现故障了怎么办?

  TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
另一个说法 定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。接着就关闭连接。

TCP连接异常终止(RST包)
  • TCP的异常终止是相对于正常释放TCP连接的过程而言的,我们都知道,TCP连接的建立是通过三次握手完成的,而TCP正常释放连接是通过四次挥手来完成,但是有些情况下,TCP在交互的过程中会出现一些意想不到的情况,导致TCP无法按照正常的四次挥手来释放连接,如果此时不通过其他的方式来释放TCP连接的话,这个TCP连接将会一直存在,占用系统的部分资源。
    TCP异常终止的常见情形
  • 客户端尝试与服务器未对外提供服务的端口建立TCP连接,服务器将会直接向客户端发送reset报文。
  • 客户端和服务器的某一方在交互的过程中发生异常(如程序崩溃等),该方系统将向对端发送TCP reset报文,告之对方释放相关的TCP连接,
  • 在交互的双方中的某一方长期未收到来自对方的确认报文,则其在超出一定的重传次数或时间后,会主动向对端发送reset报文释放该TCP连接

TCP状态转移图:

  • CLOSED: 这个没什么好说的了,表示初始状态。
  • LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。
  • SYN_RCVD: 这个状态表示接受到了SYN报文,
  • SYN_SENT: 这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状 态,并等待服务端的发送三次握手中的第2个报文。
  • ESTABLISHED: 这个容易理解了,表示连接已经建立了。
  • FIN_WAIT_1(重要): 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别 是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即 进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,
  • FIN_WAIT_2(重要):
  • TIME_WAIT(重要): 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。

基于TCP的Socket编程

  • 服务端和客户端初始化 socket,得到文件描述符;
  • 服务端调用 bind,将绑定在 IP 地址和端口;
  • 服务端调用 listen,进行监听客户端申请的连接;设置允许的最大连接数
  • 服务端调用 accept,等待客户端连接;
  • 客户端调用 connect,向服务器端的地址和端口发起连接请求;
  • 服务端 accept 返回用于传输的 socket 的文件描述符;
  • 客户端调用 write 写入数据;服务端调用 read 读取数据;(用函数send()和recv(),或者read()和write())
  • 客户端断开连接时,会调用 close,那么服务端 read 读取数据的时候,就会读取到了 EOF,待处理完数据后,服务端调用 close,表示连接关闭。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gcuMK8Np-1619366662346)(…/index/socket.jpeg)]

基于UDP的Socket编程

  服务器端流程:

  • 1.建立套接字文件描述符,使用函数socket(),生成套接字文件描述符。
  • 2.绑定侦听端口,使用bind()函数
  • 3.接收客户端的数据,使用recvfrom()函数接收客户端的网络数据。
  • 4.向客户端发送数据,使用sendto()函数向服务器主机发送数据。
  • 5.关闭套接字,使用close()函数释放资源。UDP协议的客户端流程

  客户端流程

  • 1.建立套接字文件描述符,socket()。
  • 2.设置服务器地址和端口,struct sockaddr。
  • 3.向服务器发送数据,sendto()。
  • 4.接收服务器的数据,recvfrom()。
  • 5.关闭套接字,close()。

Socket编程的send() recv() accept() socket()函数?

  • socket():这个函数主要用于建立一个对应参数的套接字文件描述符

  • bind():主要用以将套接字和本地的端口链接起来。

  • send()函数用来向TCP连接的另一端发送数据。客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答,send的作用是将要发送的数据拷贝到缓冲区,协议负责传输。

  • recv()函数用来从TCP连接的另一端接收数据,当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,然后从缓冲区中读取接收到的内容给应用层。

  • accept()函数用了接收一个连接,内核维护了半连接队列和一个已完成连接队列,当队列为空的时候,accept函数阻塞,不为空的时候accept函数从上边取下来一个已完成连接,返回一个文件描述符。

  • 客户端发送SYN付服务端进行第一次报文握手,此时服务端将此请求信息放在半连接队列中并回复SYN+ACK给客户端。此处就是SYN Flood(后续关注,此篇记录)攻击的点,攻击方要做的就是不停的建立连接,但是确不给出ACK确认,导致半连接队列满了,其他请求无法进入。

  • 客户端收到SYN+ACK,随机发出ACK确认给服务端;全队列未满:从半连接队列拿出此消息放入全队列中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值