计算机网络基础(一)TCP/IP与UDP

1 TCP特性

01.TCP的特点

  • 具备的特点
    • TCP是面向连接的传输层协议。
    • TCP连接是点对点的(套接字–IP:Port到套接字)。
    • TCP提供可靠交付的服务。
    • TCP提供全双工通信。
    • 面向字节流。

02.TCP:基本概念

全名:Transmission Control Protocol

  • 发送缓存和接受缓存
    • 用来临时保存双向通信的数据。在发送时,应用程序将数据传送给TCP发送缓存后,就可以做自己的事情,TCP在合适的时候发送数据;在接受数据时,TCP把发送的数据放入缓存,上层应用在合适的时候读取缓存即可。
  • 滑动窗口
    • TCP的滑动窗口以字节为单位,用3个指针进行表示。当窗口内连续报文段被确认收到后,可以将窗口向前滑动。窗口大小应小于等于缓存区的大小。
  • 滑动窗口协议
    • 只有在接收窗口向前滑动时(与此同时也发送了确认),发送窗口才有可能向前滑动。收发两端的窗口按照以上规律不断地向前滑动,因此这种协议又称为滑动窗口协议。
      • 当发送窗口和接收窗口的大小都等于 1时,就是停止等待协议。
      • 当发送窗口大于1,接收窗口等于1时,就是回退N步协议。
      • 当发送窗口和接收窗口的大小均大于1时,就是选择重发协议。

03.TCP报文结构

  • 报文结构如下所示
    • 源端口、目的端口:16位长。标识出远端和本地的端口号。
    • 序列号:32位长。表明了发送的数据报的顺序,不一定从0开始。
    • 确认号:32位长。希望收到的下一个数据报的序列号,表明到序列号N-1为止的所有数据已经正确收到。
    • TCP协议数据报头长:4位长。表明TCP头中包含多少个32位字。
    • 接下来的6位未用。
    • ACK:(active)ACK位置1表明确认号是合法的。如果ACK为0,那么数据报不包含确认信息,确认字段被省略。
    • PSH:表示是带有PUSH标志的数据。接收方因此请求数据报一到便可送往应用程序而不必等到缓冲区装满时才传送。
    • RST:用于复位由于主机崩溃或其它原因而出现的错误的连接。还可以用于拒绝非法的数据报或拒绝连接请求。
    • SYN:(*Synchronize Sequence Numbers*)用于建立连接。
    • FIN:(Finish)用于释放连接。
    • 窗口大小:16位长。窗口大小字段表示在确认了字节之后还可以发送多少个字节。
    • 校验和:16位长。是为了确保高可靠性而设置的。它校验头部、数据和伪TCP头部之和。
    • 紧急指针:URG=1时才有意义。
    • 可选项:长度可变,最长40个字节。
      • MMS
      • SACK:选择确认。
      • 时间戳:计算往返时间;用于处理TCP序号超过2^32的情况,又称为防止序号回绕(PAWS)。
  • TCP最小长度为20个字节。

2 TCP三次握手

01.三次握手原理图

  • 第一次:发送SNY=1表示此次握手是请求建立连接的,然后seq生成一个客户端的随机数X
  • 第二次:发送SNY=1,ACK=1表示是回复请求建立连接的,然后ack=客户端的seq+1(这样客户端收到后就能确认是之前想要连接的那个服务端),然后把服务端也生成一个代表自己的随机数seq=Y发给客户端。
  • 第三次:ACK=1。 seq=客户端随机数+1,ack=服务端随机数+1(这样服务端就知道是刚刚那个客户端了)
    image

02.为何三次握手

  • 为什么建立连接需要三次握手
    • 首先非常明确的是两次握手是最基本的,第一次握手,C端发了个连接请求消息到S端,S端收到后S端就知道自己与C端是可以连接成功的,但是C端此时并不知道S端是否接收到这个消息,所以S端接收到消息后得应答,C端得到S端的回复后,才能确定自己与S端是可以连接上的,这就是第二次握手。
    • C端只有确定了自己能与S端连接上才能开始发数据。所以两次握手肯定是最基本的。
    • 那么为什么需要第三次握手呢?假设一下如果没有第三次握手,而是两次握手后我们就认为连接建立,那么会发生什么?
    • 第三次握手是为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误
  • 具体情况就是:
    • C端发出去的第一个网络连接请求由于某些原因在网络节点中滞留了,导致延迟,直到连接释放的某个时间点才到达S端,这是一个早已失效的报文,但是此时S端仍然认为这是C端的建立连接请求第一次握手,于是S端回应了C端,第二次握手。
    • 如果只有两次握手,那么到这里,连接就建立了,但是此时C端并没有任何数据要发送,而S端就会傻傻的等待着,造成很大的资源浪费。所以需要第三次握手,只有C端再次回应一下,就可以避免这种情况。

04.四次握手断开连接

  • 如图所示:
    • image
  • 大概流程如下所示
    • 经过上面的建立连接图的解析,这个图应该不难看懂,这里主要有一个问题:为什么比建立连接时多了一次握手?
    • 可以看到这里服务端的ACK(回复客户端)和FIN(终止)消息并不是同时发出的,而是先ACK,然后再FIN,这也很好理解,当客户端要求断开连接时,此时服务端可能还有未发送完的数据,所以先ACK,然后等数据发送完再FIN。
    • 由于TCP连接是全双工的,因此每个方向都必须单独关闭。客户端在数据发送完毕后发送一个结束数据段FIN,且服务端也返回确认数据段ACK,此时结束了客户端到服务端的连接;然后客户端接收到服务端发送的FIN,且服务端也收到了ACK之后,自此双方的数据通信完全结束。简单说来是“先关读,后关写”,一共需要四个阶段:服务器读通道关闭->客户机写通道关闭->客户机读通道关闭->服务器写通道关闭。这样就变成了四次握手了。

05.常见面试题

  • TCP采用四次挥手关闭连接如图所示为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

    • 这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

    简而言之就是关闭的时候需要确认对方和自己都同意可以关闭了,才关闭

3 TCP数据传输

01.先看TCP特点

  • ②TCP协议:
    • 必须建立连接,形成传输数据的通道
    • 在连接中可进行大数据量传输
    • 通过三次握手完成连接,是可靠协议
    • 必须建立连接,效率会稍低
  • 那么你知道为tcp如何保证传输是可靠的,为何效率会低一些?

02.如何保证可靠传输

  • TCP 协议如何保证可靠传输
    • 1.应用数据被分割成 TCP 认为最适合发送的数据块。
    • 2.TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
    • 3.校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
    • 4.TCP 的接收端会丢弃重复的数据。
    • 5.流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
    • 6.拥塞控制: 当网络拥塞时,减少数据的发送。
    • 7.停止等待协议 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

03.TCP流量控制

  • 流量控制指点对点通信量的控制,是端到端正的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。这里是通过滑动窗口机制来实现的。发送方的发送窗口不能超过接收方的接收窗口。TCP的窗口单位是字节,不是报文段。
    • image
    • 这上图中B一共进行了三次流量控制:第一次将窗口减小到300,第二次减小到100,最后减小到0,这时发送方暂停发送知道B发送一个新的窗口值为止。
    • 如果B发送了一个新的窗口值到A,但是A并没有收到,就会造成死锁。为解决这个问题,TCP为每个链接设置有一个持续计时器。只要TCP收到一个0窗口,就启动计时器。若计时器设置的时间到了,就发送一个探测报文,而接收方在确认的时候会给出一个现在的窗口值。

04.TCP拥塞控制

  • 防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
4.1 慢开始和拥塞避免
  • 发送方维持一个拥塞窗口cwnd的状态变量。发送方让自己的发送窗口小于等于拥塞窗口
    • image
  • 慢开始由小到大的逐渐增大拥塞窗口。首先将cwnd设置为一个最大报文段MMS,在收到一个对新的报文段的确认后,把拥塞窗口增加一个MMS。——指数增长
  • 拥塞避免:当慢开始到门限值(ssthresh)后,使用拥塞避免算法(cwnd每次加1)。当发现网络拥塞后,将cwnd置为1,ssthresh减半,再次执行慢开始。
4.2 快重传和快恢复
  • 快重传当接收方收到一个失序报文段后就立即发送重复确认而不要等到自己发送数据时捎带确认。当发送方连续收到三个重复确认时,应立即重传接收方尚未收到的报文段。
  • 快恢复:与快重传结合使用。
    • 在连续收到三个重复确认时,将慢开始的ssthresh减半,这是为了防止网络拥塞( ** 接下来并不执行慢开始 ** )。
    • 由于发送方现在认为 网络很可能没有拥塞,于是接下来不执行慢开始,而是将cwnd值设置为ssthresh减半后的值,然后执行拥塞避免。

05.停止等待协议

5.1 无差错情况
  • 发送方发送分组,接收方在规定时间内收到,并且回复确认.发送方再次发送。
    • image
5.2 出现差错情况
  • 停止等待协议中超时重传是指只要超过一段时间仍然没有收到确认,就重传前面发送过的分组(认为刚才发送过的分组丢失了)。因此每发送完一个分组需要设置一个超时计时器,其重转时间应比数据在分组传输的平均往返时间更长一些。这种自动重传方式常称为 自动重传请求 ARQ 。另外在停止等待协议中若收到重复分组,就丢弃该分组,但同时还要发送确认。连续 ARQ 协议 可提高信道利用率。发送维持一个发送窗口,凡位于发送窗口内的分组可连续发送出去,而不需要等待对方确认。接收方一般采用累积确认,对按序到达的最后一个分组发送确认,表明到这个分组位置的所有分组都已经正确收到了。
    • image
5.3 确认丢失和确认迟到
  • 确认丢失:确认消息在传输过程丢失
    • 当A发送M1消息,B收到后,B向A发送了一个M1确认消息,但却在传输过程中丢失。而A并不知道,在超时计时过后,A重传M1消息,B再次收到该消息后采取以下两点措施:
    • 1.丢弃这个重复的M1消息,不向上层交付。
    • 2.向A发送确认消息。(不会认为已经发送过了,就不再发送。A能重传,就证明B的确认消息丢失)。
  • 确认迟到 :确认消息在传输过程中迟到
    • A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下:
    • 1.A收到重复的确认后,直接丢弃。
    • 2.B收到重复的M1后,也直接丢弃重复的M1。

06.传输伪代码

6.1 客户端发送数据
/**
 * 端口号
 */
private static final int PORT = 8080;

/**
 * @param serverAddress 要发送到服务端的ip
 * 1.创建socket并指定ip和端口号
 * 2.获取输出流,写数据
 * 3.释放资源
 * 4.Tcp一定要先开接收端
 */
public void send_tcp(String serverAddress) {
    try {
        Socket s = new Socket(serverAddress, PORT);
        //为了发送数据,应该获得socket流中的输出流
        OutputStream out = s.getOutputStream();
        String content = "yang";
        out.write(content.getBytes());
        s.close();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
6.2 服务端接收数据
/**
 * TCP协议接收数据
 * 1.创建接收端的Socket对象
 * 2.监听客户端接收,返回一个Socket对象
 * 3.获取输入流,读取数据显示在控制台
 * 4.释放资源
 */
public void receive_tcp() {
    try {
        //1.建立连接,监听端口
        ServerSocket ss = new ServerSocket(PORT);
        //2.连接客户端对象
        while (true) {
            //阻塞式方法,只有客户端连接了才会继续往下运行
            Socket accept = ss.accept();
            //获取ip
            String ip = accept.getInetAddress().getHostAddress();
            //3.获取客户端发送过来的数据
            InputStream in = accept.getInputStream();
            //4.开始读取,获取输入信息
            BufferedReader bff = new BufferedReader(new InputStreamReader(in));
            //读取信息
            String line;
            final StringBuilder sb = new StringBuilder();
            while ((line = bff.readLine()) != null) {
                sb.append(line);
            }
            Message message = new Message();
            message.obj = sb.toString();
            handler.sendMessage(message);
            //5.关闭
            //ss.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

4 UDP传输数据

01.客户端发送数据

  • 客户端发送数据
/**
 * 端口号
 */
private static final int PORT = 8080;

/*
 * UDP协议发送数据:
 * 1.创建发送端Socket对象
 * 2.创建数据,并把数据打包
 * 3.调用Socket对象发送方法发送数据包
 * 4.释放资源
 */
private void udpSendMessage(String serverAddress) {
    String content = "yang";
    // 创建发送端Socket对象
    try {
        // 创建发送端Socket对象
        DatagramSocket ds = new DatagramSocket();
        // 创建数据,并把数据打包
        byte[] bys = content.getBytes();
        InetAddress byName = InetAddress.getByName(serverAddress);
        DatagramPacket dp = new DatagramPacket(bys, bys.length,byName ,PORT);
        // 调用Socket对象发送方法发送数据包
        ds.send(dp);
        // 释放资源
        ds.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

02.服务端接收数据

  • 服务端接收数据
/*
     * UDP协议接收数据:
     * 1.创建接收端Socket对象
     * 2.创建一个数据包(接收容器)
     * 3.调用Socket对象接收方法接收数据包
     * 4.解析数据包
     * 5.释放资源
     */
private void receive_udp() {
    try {
        // 创建接收端Socket对象
        DatagramSocket ds = new DatagramSocket(PORT);
        // 创建一个数据包(接收容器)
        byte[] bys = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys, bys.length);
        // 调用Socket对象接收方法接收数据包
        ds.receive(dp);
        // 获取对方的ip
        String ip = dp.getAddress().getHostAddress();
        // 解析数据
        String data = new String(dp.getData(), 0, dp.getLength());
        Message message = new Message();
        message.obj = data;
        message.what = 2;
        handler.sendMessage(message);
        // 关闭数据库
        ds.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

5 TCP和UDP

01.TCP和UDP的区别

  • ①UDP协议:
    • 面向无连接
    • 每个数据报的大小在限制在64k内
    • 因为是面向无连接,所以是不可靠协议
    • 不需要建立连接,速度快
  • ②TCP协议:
    • 必须建立连接,形成传输数据的通道
    • 在连接中可进行大数据量传输
    • 通过三次握手完成连接,是可靠协议
    • 必须建立连接,效率会稍低
  • 注:三次握手:
    • 第一次:我问你:在么?
    • 第二次:你回答:在。
    • 第三次:我反馈:哦,我知道你在。

02.发微信和看视频

  • 微信发送文件,应该是TCP协议,而网络播放视频适合用UDP。
    • UDP适用于对网络通讯质量要求不高、要求网络通讯速度能尽量快的实时性应用;
    • TCP适用于对网络通讯质量有要求的可靠性应用。
    • 播放视频区分关键帧和普通帧,虽然UDP会丢帧但如果只是丢普通帧损失并不大,取而代之的是高速率和实时性。

6 IP协议

01.什么是IP地址

  • IP协议是什么?
    • IP协议:用于将多个包交换网络连接起来的,它在源地址和目的地址之间传送一种称之为数据包的东西,它还提供对数据大小的重新组装功能,以适应不同网络对包大小的要求。
  • 域名是干什么的?
    • 域名只是为了方便阅读和记忆,计算机并不能直接处理,还需要通过域名服务器(DNS)把域名解析为对应的IP地址才能进行网络访问。因此直接在网络浏览器的地址栏中输入相应的IP地址也是可以访问网络的。

02.域名解析IP

  • 这块看DNS域名解析

03.IPv4的协议包封装结构

  • IPv4的协议包封装结构是什么?
    • image
  • 该结构中的每个数据域的意思?
    • 版本号(VERS): 4比特,表示IP协议版本号。目前的版本号是4,即IPv4。版本号规定了数据报的格式。版本不同,其数据报格式也有所不同,如IPv6的报文结构就和IPv4的结构不同。
    • 报文头长度(HLEN): 4比特,表示报文头长度。报文头长度以4 Byte为单位计算。除IP选项(IP Options)和填充(Padding)字段可以不存在外,其他各字段必须存在。这些必须存在的字段是5个4 Byte,共20 Byte长。因此,报文头长度值一般是5 。又由于报文头长度必须是32比特的整数倍,所以当一个含有IP选项字段的IP数据报不是32比特的整数倍时,由填充字段用0补足。
    • 服务类型(Type of Service): ToS字段,8比特,指示对本数据报的处理方式。它主要用来指示数据报的优先权及传输类型。QoS技术就是使用此字段对数据进行标记优先级的。
    • **总长(Total Length):**16比特,以Byte为单位表示整个IP数据报长度,包括报文头及其携带的数据。因为总长字段是16比特,所以IP数据报最长可达216 1=65 535字节。
    • 标识(Identification): 16比特,是发送者赋予数据报的标识符,接收者利用这个信息和源地址判断收到的分组属于哪个数据报,以便进行重组。因此,在分片时,该域必须不加修改地复制到各分片的报文头中。
    • 标志(Flags): 3比特,只有低两位有效。第一比特为0时表示该分片是最后一片,如果该位是1表示后面还有分片。第二比特为0时表示可以对数据报进行分片,如果该位是1表示数据报不能分片。当该位设置为1而帧长度不匹配又必须分片时,设备就会将数据报丢弃并返回错误信息。
    • 片偏移(Fragment Offset):指示本分片数据在初始数据报数据区中的偏移量,偏移量以8 Byte为单位,重组时分片顺序由片偏移提供。
    • 生存时间(Time To Live):简称TTL,8比特,用来控制数据报在网络中存在的时间。目前TTL的值并不代表时间,而是代表经由路由器的个数。数据报每经过一台路由器时,路由器将TTL值减1,一旦TTL=0,系统就丢弃该数据报,并返回错误信息。这样避免了路由出现环路时数据报在路由器之间无休止地循环。
    • 协议(Protocol): 8比特,表示该数据报携带的数据是由哪个上层协议封装的,也就是指示传输层的协议类型。如最常见的协议类型是TCP或UDP。
    • 头校验和(Header Checksum): 16比特,用于保证IP头数据的完整性。
    • 地址(Address):分为源IP地址和目的IP地址,各占32比特,表明数据的来源及其到达的目的地。
    • 填充(Padding):当IP报文头长度不是32比特的整数倍时,填充0来凑齐32比特整数倍,没有实际意义。
    • 数据(Data):来自第4层的数据段。

04.子网掩码作用

  • 子网掩码的作用主要是什么?
    • 子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分。
    • 用于子网掩码的位数决定于可能的子网数目和每个子网的主机数目。
    • 计算方法示例,定义子网掩码的步骤为:
      • A、确定哪些组地址归我们使用。比如我们申请到的网络号为 “210.73.a.b”,该网络地址为c类IP地址,网络标识为“210.73.a”,主机标识为“b”。
      • B、根据我们所需的子网数以及将来可能扩充到的子网数,用宿主机的一些位来定义子网掩码。比如我们需要12个子网,将来可能需要16个。用第四个字节的前四位确定子网掩码。前四位都置为“1”,即第四个字节为“11110000”,这个数我们暂且称作新的二进制子网掩码。
      • C、把对应初始网络的各个位都置为“1”,即前三个字节都置为“1”,则子网掩码的间断二进制形式为:“11111111.11111111.11111111.11110000” 。
      • D、把这个数转化为间断十进制形式为:“255.255.255.240” 。

05.MAC与IP区别

  • 不同的特点主要有:
    • 对于网络上的某一设备,如一台计算机或一台路由器,其IP地址是基于网络拓扑设计出的,同一台设备或计算机上,改动IP地址是很容易的(但必须唯一),而MAC则是生产厂商烧录好的,一般不能改动。我们可以根据需要给一台主机指定任意的IP地址,如我们可以给局域网上的某台计算机分配IP地址为192.168.0.112 ,也可以将它改成192.168.0.200。而任一网络设备(如网卡,路由器)一旦生产出来以后,其MAC地址不可由本地连接内的配置进行修改。如果一个计算机的网卡坏了,在更换网卡之后,该计算机的MAC地址就变了。
    • 长度不同。IP地址为32位,MAC地址为48位。
    • 分配依据不同。IP地址的分配是基于网络拓扑,MAC地址的分配是基于制造商。
    • 寻址协议层不同。IP地址应用于OSI第三层,即网络层,而MAC地址应用在OSI第二层,即数据链路层。 数据链路层协议可以使数据从一个节点传递到相同链路的另一个节点上(通过MAC地址),而网络层协议使数据可以从一个网络传递到另一个网络上(ARP根据目的IP地址,找到中间节点的MAC地址,通过中间节点传送,从而最终到达目的网络)。

7 Socket编程

01.Socket简单介绍

  • Socket简单介绍
    • Socket就是为网络服务提供的一种机制
    • 通信的两端都有Socket
    • 网络通信其实就是Socket间的通信
    • 数据在两个Socket间通过IO传输
    • 玩Socket主要就是记住流程,代码查文档就行
    • Socket的简单使用的话应该都会,两个端各建立一个Socket,服务端的叫ServerSocket,然后建立连接即可。

02.Socket工作图解

  • 如下所示
    • image

03.Socket建立网络连接

  • Socket建立网络连接的步骤是什么?
    • 建立Socket连接至少需要一对套接字,其中一个运行与客户端–ClientSocket,一个运行于服务端–ServiceSocket
      • 1、服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
      • 2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。注意:客户端的套接字必须描述他要连接的服务器的套接字,
      • 指出服务器套接字的地址和端口号,然后就像服务器端套接字提出连接请求。
      • 3、连接确认:当服务器端套接字监听到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述
      • 发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务端套接字则继续处于监听状态,继续接收其他客户端套接字的连接请求。

8 数据包处理

01.先看一个案例

  • 假设甲给乙发送邮件,内容为:“早上好”。而从 TCP/IP 通信上看,是从一台计算机 A 向另一台计算机 B 发送邮件。我们通过这个例子来讲解一下 TCP/IP 通信的过程。
    • image

02.数据包的发送处理

  • 1.应用程序处理
    • 启动应用程序新建邮件,将收件人邮箱填好,再由键盘输入“早上好”,鼠标点击“发送”按钮就可以开始 TCP/IP 的通信了。
    • 首先,应用程序会对邮件内容进行编码处理,例如:UTF-8,GB2312 等。这些编码相当于 OSI 的表示层功能。应用在发送邮件的那一刻建立 TCP 连接,从而利用这个 TCP 连接发送数据。它的过程首先是将应用的数据发送给下一层的 TCP,在做实际的转发处理。
  • 2.TCP 模块处理
    • TCP根据应用的提示,负责建立连接,发送数据以及断开连接。TCP 提供将应用层发来的数据顺利发送至对端的可靠传输。
    • 为了实现 TCP 的这一功能,需要在应用层数据的前端附加一个 TCP 的首部。TCP 的首部中包括源端口号和目标端口号、序号。随后将附加了 TCP 首部的包再发送给 IP。
  • 3.IP 模块处理
    • IP 将 TCP 传过来的 TCP 首部和 TCP 数据合起来当做自己的数据,并在 TCP 首部的前端加上自己的 IP 首部。IP 首部中包含接收端 IP 地址,发送端 IP 地址。随后 IP 包将被发送给连接这些路由器或主机网络接口的驱动程序,以实现真正的发送数据。
  • 4.网络接口(以太网驱动)的处理
    • 从 IP 传过来的 IP 包,对于以太网卡来说就是数据。给这些数据附加上以太网首部并进行发送处理。以太网首部中包含接收端 MAC 地址,发送端 MAC 地址,以太网类型,以太网数据协议。根据上述信息产生的以太网数据将被通过物理层传输给接收端。

03.数据包的接收处理

  • 1.网络接口(以太网驱动)的处理
    • 主机收到以太网包以后,首先从以太网的包首部找到 MAC 地址判断是否为发给自己的包。如果不是发给自己的则丢弃数据,如果是发给自己的则将数据传给处理 IP 的子程序。
  • 2.IP 模块处理
    • IP 模块收到 IP 包首部以及后面的数据部分以后,也做类似的处理。如果判断得出包首部的 IP 地址与自己的 IP 地址匹配,则可接受数据并从中查找上一层的协议。并将后面的数据传给 TCP 或者 UDP 处理。对于有路由的情况下,接收端的地址往往不是自己的地址,此时需要借助路由控制表,从中找出应该送到的主机或者路由器以后再进行转发数据。
  • 3.TCP 模块处理
    • 在 TCP 模块中,首先会校验数据是否被破坏,然后检查是否在按照序号接收数据。最后检查端口号,确定具体的应用程序。数据接收完毕后,接收端则发送一个“确认绘制”给发送端。数据被完整地接收以后,会传给由端口号识别的应用程序。
  • 4.应用程序处理
    • 接收端应用程序会直接接收发送端发送的数据。通过解析数据可以获知邮件的内容信息。

9 ARQ协议

01.什么是ARQ协议

  • ARQ协议(自动重传请求)是OSI模型中数据链路层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。

02.停止等待ARQ

  • 发送点对接收点发送数据包,然后等待接收点回复ACK并且开始计时。
  • 在等待过程中,发送点停止发送新的数据包。
  • 当数据包没有成功被接收点接收时候,接收点不会发送ACK.这样发送点在等待一定时间后,重新发送数据包。
  • 反复以上步骤直到收到从接收点发送的ACK。
  • 这个协议的缺点
    • 是较长的等待时间导致低的数据传输速度。在低速传输时,对连接频道的利用率比较好,但是在高速传输时,频道的利用率会显著下降。

03.连续ARQ协议(累积确认)

  • 为了克服停止并等待ARQ协议长时间等待ACK的缺点。这个协议会连续发送一组数据包,然后再等待这些数据包的ACK。在连续ARQ协议中涉及到滑动窗口协议,这是TCP协议的精髓所在。
  • 优点:
    • 信道利用率高,容易实现,即使确认丢失,也不必重传。
  • 缺点:
    • 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5条 消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。
3.1 回退N重传
  • 接收点丢弃从第一个没有收到的数据包开始的所有数据包。
  • 发送点收到NACK后,从NACK中指明的数据包开始重新发送。
3.2 选择重传(SACK)
  • 发送点连续发送数据包但对每个数据包都设有个一个计时器。
  • 当在一定时间内没有收到某个数据包的ACK时,发送点只重新发送那个没有ACK的数据包。
  • 相对于回退N重传来说,选择重传可以减少重传的数据。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值