zoukankan      html  css  js  c++  java
  • TCP协议

    • TCP包头中的序号是为了解决乱序的问题,给包编号可以确定先来后到。

    • TCP包头中的确认序号是为了解决不丢包的问题,发出去的包应该需要确认对方是否收到,如果没有收到就应该重新发送,直到送达。

    • 从IP层面来讲,如果网络状况比较差,则IP层的数据是没有任何可靠性保证的,而作为IP层的上一层TCP也无能为力,TCP层唯一能做的就是不断重传,在它的层面上通过各种算法保证努力保证可靠性。

    • TCP包头中的状态位比如:发起一个连接SYN,回复ACK,重新连接RST,结束连接FIN等。TCP是面向连接的,因而双方要维护连接的状态,这些带状态位的包的发送,会引起双方的状态变更。

    • TCP包头中的窗口大小是为了做流量控制,通信双方各声明一个窗口,标识自己当前能够处理的能力。TCP还会做拥塞控制,控制发送的速度。
    • TCP的连接建立,常称为三次握手,因为三次就可以做到双方的消息都有去有回。具体过程如下:

        A.第一次握手是由客户端向服务端发起的,是用来去发起一个连接建立的请求,在报文中,SYN位会被标记为1,序列号为x;

        B.第二次握手是由服务器向客户端发起的,是服务器来确认一个请求连接的,在报文中,ACK位和SYN位都会被标记为1,序列号为y,确认报文x(ack = x + 1);

        C.第三次握手是客户端发给服务器的,是对服务器的上一个报文的一个确认报文,这个报文中的ACK被标记为1,序列号为x+1,确认报文y(ack = y + 1)。

      概括为:客户端 -> SYN -> 服务端

               服务端 -> SYN/ACK -> 客户端

               客户端 -> ACK -> 服务端

    • 三次握手除了双方建立连接外,主要还是为了沟通TCP包的序号的问题。每个连接都要有不同的序号,这个序号的起始序号是随着时间变化的。

    • 双方建立连接后,为了维护这个连接,双方都要维护一个状态机,在连接建立的过程中,双方的状态变化时序图如图所示。具体为:

        A.一开始,左边的客户端和右边的服务端都处于CLOSED状态,先是服务端主动监听某个端口,处于LISTEN状态;
        B.然后客户端主动发起连接SYN,之后处于SYN-SENT状态;
        C.服务端收到发起的连接,返回SYN,并且回复客户端的SYN,之后处于SYN-RCVD状态;
        D.客户端收到服务端发送的SYN和ACK之后,发送ACK的ACK,之后处于ESTABLISHED状态;
        E.服务端收到ACK的ACK之后,也处于ESTABLISHED状态。

    • TCP的连接结束,常成为四次挥手。具体过程如下:

      A.第一次挥手是客户端向服务器发起的,这个时候客户端已经完成了数据发送,会发起一个包去进行连接断开的请求,这个报文中的FIN位被标记为1,序列号为p;

      B.第二次挥手是服务器发给客户端的,这个报文是用来确认上一个客户端断开连接请求的一个报文,ACK被标记为1,确认报文p(ack = p + 1);
      C.第三次挥手同样是服务器发给客户端的,此时服务器的数据如果也发送完毕的话,服务器会向客户端发起一个断开连接的申请,在这个报文中,ACK和FIN位都会被标记为1,序列号为q,确认报文p(ack = p + 1);
      D.第四次挥手是客户端发给服务器的,是用来确认服务器的上一个断开连接的,ACK位被标记为1,确认报文q(ack = q + 1)。
      概括为:客户端 -> FIN -> 服务端
          服务端 -> ACK -> 客户端
          服务端 -> FIN -> 客户端
          客户端 -> ACK -> 服务端

    • MSL是报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为TCP报文是基于IP协议的,而IP头中有一个TTL域,是IP数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送报文通知源主机。协议规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

    • 将连接建立和连接断开的两个时序状态图综合起来,就得到著名的TCP状态机。
    • TCP协议为了保证顺序性,每一个包都有一个ID序号。在建立连接时,会商定起始的ID序号,然后按照ID一个个发送;为了保证不丢包,对于发送的包都要进行应答,但是这个应答不是一个个来的,而是会应答某个之前的ID,表示都收到了,这种模式称为累计确认或者累计应答。

    • 为了记录所有发送的包和接收的包,TCP需要发送端和接收端分别都有缓存来保存这些记录。
    • 发送端缓存里的包是按照包的ID一个个排列,根据处理的情况分成四个部分:

        第一部分:发送了并且已经确认的。

        第二部分:发送了并且尚未确认的。

        第三部分:没有发送,但是已经等待发送的。

        第四部分:没有发送,并且暂时还不会发送的。

    • 发送端缓存区分第三和第四部分是为了做流量控制,在TCP里,接收端会给发送端报一个窗口的大小,这个窗口的大小应该等于第二部分加上第三部分,超过这个窗口的,接收端处理不过来,就不能发送。

    • 对于接收端,它的缓存里记录三部分内容:

        第一部分:接受并且确认过的。

        第二部分:还没接收,但是马上就能接收的。

        第三部分:还没接收,也没法接收的。

    • 顺序问题、丢包问题、流量控制都是通过滑动窗口来解决。拥塞控制通过拥塞窗口来解决。
  • 相关阅读:
    FZU 2169 shadow (用了一次邻接表存边,树形DP)
    win7中USB音箱没有声音解决的方法
    关于port的关闭——Linux
    JS来推断文本框内容改变事件
    hibernate 实体关系映射笔记
    java中接口的定义与实现
    理解WebKit和Chromium: 调试Android系统上的Chromium
    iOS与日期相关的操作
    Java正則表達式入门
    Windows内核之线程的调度,优先级,亲缘性
  • 原文地址:https://www.cnblogs.com/kongzimengzixiaozhuzi/p/13285522.html
Copyright © 2011-2022 走看看