🌐计算机网络

password
icon
AI summary
type
status
date
slug
summary
tags
category
Property
Oct 21, 2024 01:26 PM

TCP/IP网络模型

为了方便不同设备之间的进程通信,兼容多种多样的设备,协商出一套通用的网络协议,这就是TCP/IP网络模型的来由
notion image
  • 应用层:专注与为用户提供应用功能,比如HTTP、FTP、Telnet、DNS、SMTP等
  • 传输层:为应用层提供网络支持,有两个传输协议:
    • TCP:可靠传输,有很多特性:比如流量控制、超时重传、拥塞控制等
    • UDP:实时性更好

socket 什么情况下可读或可写?

可读:
  1. socket 接收缓冲区中已经接收的数据的字节数大于等于 socket接收缓冲区低水位标记的当前值; 对这样的 socket 的读操作不会阻塞, 并返回一个大于 0 的值 (准备好读入的数据的字节数).
  1. 连接的读半部关闭 (即: 接收到对方发过来的 FIN 的 TCP 连接), 并且返回 0;
  1. socket 为监听套接字且收到了对方的 connect 请求已经完成的连接数为非 0. 这样的 soocket 处于可读状态;
  1. 存在一个套接字错误待处理,这时 socket 的读操作将不会阻塞, 并且返回一个错误 (-1)。
可写:
  1. socket 发送缓冲区中的可用空间字节数大于等于 socket发送缓冲区低水位标记的当前值, 且 (i):socket 已连接 (TCP socket), 或者 (ii):socket 不要求连接 (如: UDP socket). 这意味着, 如果我们将这样的 socket 设置为非阻塞模式, 写操作将不会阻塞, 并且返回一个正值 (如: 由传输层接收的字节数). 我们可以用 socket 选项 SO_SNDLOWAT 来设置此低水位标记, 对于 TCP 和 UDP socket, 其缺省值一般是 2048Bytes;
  1. 连接的写半部关闭. 对于这样的 socket 的的写操作将产生信号 SIGPIPE;
  1. 使用非阻塞式 connect 的套接字已经建立连接,或 connect 已经以失败告终;
  1. 存在一个套接字错误待处理. 对于这样的 socket 的写操作将不会阻塞并且返回一个错误 (-1),errno 则设置成明确的错误条件. 这些待处理的错误也可以通过指定 socket 选项 SO_ERROR 调用 getsockopt 函数来取得并清除。

udp 调用 connect 有什么作用?

  1. 因为 UDP 可以是一对一,多对一,一对多,或者多对多的通信,所以每次调用sendto()/recvfrom()时都必须指定目标IP和端口号。通过调用 connect() 建立一个端到端的连接,就可以和 TCP 一样使用 send()/recv() 传递数据,而不需要每次都指定目标 IP 和端口号。但是它和 TCP 不同的是它没有三次握手的过程。
  1. 可以通过在已建立连接的 UDP 套接字上,调用 connect() 实现指定新的 IP 地址和端口号以及断开连接。

请回答一下 HTTP 和 HTTPS 的区别,以及 HTTPS 有什么缺点?

HTTP 协议和 HTTPS 协议区别如下:
  1. HTTP 协议是以明文的方式在网络中传输数据,而 HTTPS 协议传输的数据则是经过 TLS (Transport Layer Security, 安全传输层协议) 加密后的,HTTPS 具有更高的安全性
  1. HTTPS 在 TCP 三次握手阶段之后,还需要进行 SSL(Secure Sockets Layer 安全套接字协议) 的 handshake,协商加密使用的对称加密密钥
  1. HTTPS 协议需要服务端申请证书,浏览器端安装对应的根证书
  1. HTTP 协议端口是 80,HTTPS 协议端口是 443
HTTPS 优点:
  • HTTPS 传输数据过程中使用密钥进行加密,所以安全性更高
  • HTTPS 协议可以认证用户和服务器,确保数据发送到正确的用户和服务器
HTTPS 缺点:
  • HTTPS 握手阶段延时较高: 由于在进行 HTTP 会话之前还需要进行 SSL 握手,因此 HTTPS 协议握手阶段延时增加
  • HTTPS 部署成本高: 一方面 HTTPS 协议需要使用证书来验证自身的安全性,所以需要购买 CA 证书;另一方面由于采用 HTTPS 协议需要进行加解密的计算,占用 CPU 资源较多,需要的服务器配置或数目高

IP 地址作用和 MAC 地址作用

MAC 地址是一个硬件地址,用来定义网络设备的位置,主要由数据链路层负责。而 IP 地址是 IP 协议提供的一种统一的地址格式,为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

搜索 baidu,会用到计算机网络中的什么层?每层是干什么的

浏览器要将 URL 解析为 IP 地址,解析域名就要用到 DNS 协议,首先主机会查询 DNS 的缓存,如果没有就给本地 DNS 发送查询请求。DNS 查询分为两种方式,一种是递归查询,一种是迭代查询。如果是迭代查询,本地的 DNS 服务器,向根域名服务器发送查询请求,根域名服务器告知该域名的一级域名服务器,然后本地服务器给该一级域名服务器发送查询请求,然后依次类推直到查询到该域名的 IP 地址。DNS 服务器是基于 UDP 的,因此会用到 UDP 协议。
得到 IP 地址后,浏览器就要与服务器建立一个 http 连接。因此要用到 http 协议,http 协议报文格式上面已经提到。http 生成一个 get 请求报文,将该报文传给 TCP 层处理,所以还会用到 TCP 协议。如果采用 https 还会使用 https 协议先对 http 数据进行加密。TCP 层如果有需要先将 HTTP 数据包分片,分片依据路径 MTU 和 MSS。TCP 的数据包然后会发送给 IP 层,用到 IP 协议。IP 层通过路由选路,一跳一跳发送到目的地址。当然在一个网段内的寻址是通过以太网协议实现 (也可以是其他物理层协议,比如 PPP,SLIP),以太网协议需要直到目的 IP 地址的物理地址,有需要 ARP 协议。
从输入 URL 到页面展示的详细过程:
  1. 输入网址
  1. DNS 解析
  1. 建立 tcp 连接
  1. 客户端发送 HTTP/HTTPS 请求
  1. 服务器处理请求
  1. 服务器响应请求
  1. 浏览器展示 HTML
  1. 浏览器发送请求获取其他在 HTML 中的资源。

请问 tcp 握手为什么两次不可以?为什么不用四次?

两次不可以:tcp 是全双工通信,两次握手只能确定单向数据链路是可以通信的,并不能保证反向的通信正常 不用四次: 本来握手应该和挥手一样都是需要确认两个方向都能联通的,本来模型应该是: 1. 客户端发送 syn0 给服务器 2. 服务器收到 syn0,回复 ack(syn0+1) 3. 服务器发送 syn1 4. 客户端收到 syn1,回复 ack(syn1+1) 因为 tcp 是全双工的,上边的四部确认了数据在两个方向上都是可以正确到达的,但是 2,3 步没有没有上下的联系,可以将其合并,加快握手效率,所有就变成了 3 步握手。
不可以是两次握手:
当客户端向服务器端发送一个连接请求时,由于某种原因长时间驻留在网络节点中,无法到达服务器端,由于 TCP 的超时重传机制,当客户端在特定的时间内没有收到服务器端的的确认应答时,就会重新向服务器端发送连接请求,该请求到达服务器端并建立连接,进行数据传输,当数据传输完成时,释放了 TCP 连接。
若此时第一次的连接请求报文段延迟了一段时间后到达了服务器端,本来这是一个很早到达的失效的报文段,但是服务器端收到了该链接请求后误以为是客户端重新又发起了一次连接请求,于是服务器端发出确认应答报文段,并表示同意建立连接。如果没有第三次握手,由于服务器端发送了确认应答信息,则表示新的连接建立成功,但是客户端并没有向服务器端发送任何建立请求,客户端将忽略服务器端的确认报文,更不会发送任何请求或数据。而服务器端认为建立成功了,并一直在等待建立连接,直到超出计数器的设定值,则认为服务器端出现了异常,并关闭此链接。这个等待的过程中,浪费了服务器端的资源。

请问 TCP 三次握手是怎样的?

  1. 客户端发送 syn0 给服务器
  1. 服务器收到 syn0,回复 syn1,ack(syn0+1)
  1. 客户端收到 syn1,回复 ack(syn1+1)

四次挥手

  1. 客户端发送 fin
  1. 服务端收到 fin, 回复 ack, 然后服务器去处理其他事(Server 端所有的报文都发送完了,才能发送 FIN 报文)
  1. 服务器事情处理完,回复 fin
  1. 客户端回复 ack
客户端:发送 FIN 报文(FIN = 1),序列号为 u(seq = u),进入 FIN-WAIT 1 状态。
服务器:发送 ACK 确认报文(ACK = 1),序列号为 v(seq = v),确认报文 u(ack = u + 1),进入 CLOSE-WAIT 状态,继续传送数据。
客户端:收到上述报文进入 FIN-WAIT2 状态,继续接受 B 传输的数据。
服务器:数据传输完毕后,发送 FIN 报文(FIN = 1,ACK = 1),序列号为 w(seq = w),确认报文 u(ack = u + 1),进入 LAST-ACK 状态。
客户端:发送 ACK 确认报文(ACK = 1),序列号为 u+1(seq = u + 1),确认报文 w(ack = w + 1),进入 TIME-WAIT 状态,等待 2MSL(最长报文段寿命),进入 CLOSED 状态。
服务器:收到后上述报文后进入 CLOSED 状态。
为什么客户端不发送报文段后直接关闭,而是要等待 2MSL 个时间后才关闭?,是否有必要?
  • 若客户端发送完最后一次报文后,也就是第四次挥手后就直接进入关闭状态,此时若第四次挥手报文丢失,会导致服务器的超时重传
  • 此时客户端又已经关闭,导致不接受该报文,因此服务器会一直不断重传,并一直处于最后确认状态无法进入关闭状态
因此,有以下结论: 客户端进入时间等待状态以及处于该状态 2MSL 时长,可以确保 TCP 服务器进程可以收到最后一个 TCP 确认报文段而进入关闭状态
TCP 客户进程在发送完最后一个 TCP 确认报文段后,在经过 2MSL 时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使使下一个新的 TCP 连接中,不会出现旧连接中的报文段
若出现这样一种情况:
TCP 双方已经建立了连接,但是传输过程中 TCP 客户进程所在的主机出现了故障,此时 TCP 服务器进程以后就不能再收到 TCP 客户进程发来的数据,这时服务器进程会一直处于等待状态。
为了使 TCP 服务器进程不要再白白等待下去出现了 TCP 保活计时器。
 
上一篇
机器学习基础知识
下一篇
Python ACM 模式下的输入输出
Loading...
文章列表
Love & Share 分享热爱
Java
科研
编程四大件
算法
Rust
Python
Linux
比赛
C++
日常使用