zoukankan      html  css  js  c++  java
  • 说说TCP的三次握手

    在说这个问题之前,先说说IP协议和TCP协议

    问题:IP协议能做什么?不能做什么?

    我们都知道IP协议是无连接的通信协议,它不会占用两个正在通信的计算机的通信线路,这样就降低了IP对网络传输中的需求,每条线路都能同时满足许多不同的计算机需要,通过IP、消息、或者其他数据,会被分割为较小的独立的包,并通过因特网在计算机中传送,IP负责将每个包路由到它的目的地,但IP协议呢,没有做任何事情去确保数据包是按顺序发送是否被破坏,所以IP数据包是不可靠的。需要由它的上层协议,来做出控制------》TCP协议

    传输控制协议TCP简介

    ---》

    1、面向连接的、可靠的、基于字节流的传输层通信协议

    2、将应用层的数据流分割成报文段并发送给目标节点的TCP层(将数据打散)

    (数据传输时,应用层向TCP发送数据流,然后TCP把数据流分割成适当长度的报文段,报文段的长度呢是受该计算机连接的网络的网路层的最大连接单元限制的,则MTU的限制。TCP把结果包,传给IP层,由它来通过网络传输给对方的TCP层)

    3、数据包都有序号,对方收到则发送ACK确认,未收到则重传(怎样保证数据的有序性)

    (TCP为了保证不丢失包,就给每个包一个序号,则sequence number,这个序号就保证了数据包的按序处理,对方接受到按照这个序列来按顺序来处理数据包。接收端实体对已成功接受到的包的话,就发回一个确认,则ACK确认。如果发送端实体在合理的往返时延,则TRR内未收到的话,则认为该数据已经丢失,并且会对其重传

    4、使用校验和来检验数据在传输过程中是否有误(怎样保证数据的正确性?)

    (TCP用一个奇偶校验和函数检验数据,是否有错误,在发送和接受时呢,都要计算校验和)

    我们知道两个进程在计算机内部进行通信的话,有哪些方式?

    1、管道

    2、内存共享

    3、信号量

    4、消息队列等

    而两个进程进行通信的前提是唯一标识一个进程,通过这个唯一标识,找到对应的进程,在本地进程通信中呢,我们可以使用pid ,但用个id的话,只是在本地是唯一而已。如果把两条进程放到两台不同的计算机上,而他们要进行通信的话呢,pid就不够用了,这样的话,就需要另外的手段了,解决的方法就是在传输层中使用协议端口号,我们知道ip地址可以唯一标识主机,而ip地址+端口可以唯一标识主机中的一个进程,这样子的话,我们可以利用ip地址+协议+端口号,去标识网络中的一个进程。在一些场景下,我们称这种模式为套节字(则socket),虽然通信的重点是应用进程,但我们只要把要传输的报文交到目的主机的某一个合适的端口,剩下的工作就由TCP来完成了。

    Source Port :本机端口

    Desination Port : 目标端口

    Sequence Number : 序列号  4个字节  (例如:一段报文的序列号值是107,而携带的字段有100个字段,那么还有下一个报文的话,那么它的序列号是107+100=207)

    Acknowledgment number :确认号  4个字节(期望收到对方收到下一个报文,第一个数据字节的序号   ,例如,B收到A发送过来的报文,其序列号是301,而数据长度为200,这表明了B正确收到了A发送的到序号为500的数据,301+200-1=500,因此B期望A下次发送过来的报文的序号是501,所以B收到了A第一次报文之后,会返回ACK为501的序号的报文给B)

    Offset : 数据偏移,由于头部有可选字段,长度不固定,因此他就是指出TCP报文的数据与TCP的起始处相差多远

    Reserved:一般为0,保留域

    TCP Flags: 标记位,控制位,8个标志位,每个都代表一种功能

      1、URG --->紧急指针标记,当他为1的是紧急指针有效。为0的话,可以忽略

      2、ACK--->确认序号标志,1有效,0报文中不含确认信息,忽略确认号字段

      3、PSH--->push 标志,1带有push标志数据,如果接受方接受到这个信息,应该尽快交给应用程序处理,而不是一直停留在缓冲区

      4、RST---->重置连接标志,由于主机崩溃,或者拒绝非法的报文段,或者非法连接请求

      5、SYN---->同步序列号,用于建立连接过程。在连接请求中,SYN=1,ACK=0,表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认 SYN=1和ACK=1

      6、FIN---->finish标志,用于释放连接。为1的时候,就代表发送方没有数据发送了,则关闭本方数据流

    Window : 滑动窗口的大小,用来告知发送端和接受端的缓存大小,以此控制发送端的发送速率,从而达到流量控制

    CheckSum : 奇偶和校验,检验TCP报文段(包括TCP数据和TCP头部),以16位计算所的,由发送端计算和存储。并由接受端进行验证。

    Urgent Pointer : 紧急指针,当TCP FLAGS 为URG的时候,才有效,会显示本段报文的紧急数据的字节数

    TCP Option : 可选项,长度可变,定义一些可选参数

     

    1、为什么需要三次握手才能建立起连接呢?

    为了初始化Sequence number的初始值

    通信的双方都要通知对方自己的sequence number。也就是图上的xy,这个要作为以后通信的序号,保证应用层接受到的数据不会因为网络的问题,导致数据的乱序。就是TCP会用这个序号来拼接数据。那么服务回发信息给客户端的时候(第二次握手的时候),告诉客户端知道服务器已经知道你的seq序号了。

     

    此外在第一次握手的时候,有一个隐患。SYN的超时问题。

    首次握手的隐患-----SYN超时

    问题起因分析

    1、Server收到Client的SYN,回复SYN-ACK的时候未收到ACK确认

    2、Server不断重试直到超时,LInux默认等待63秒才断开连接(重试5次,2,4,8,16,32 共63秒)

    会将服务器连接的队列SYN耗尽,让正常的请求不能得到请求(用户就感到网络好卡,没返回)

    针对SYN Flood的防护措施

    1、linux下,SYN队列满后,通过tcp_syncookies参数回发SYN Cookie(TCP会通过原地址端口,目标地址端口,时间戳,打造一个特别sequence number回发回去,这个seq简称SYN Cookie)

    2、若为正常连接则Client会回发SYN Cookie ,直接建立连接

    问题:建立连接后,Client出现故障怎么办?

    保活机制

      1、向对方发送保活探测报文,如果未收到响应则继续发送(在一段时间,我们成为保活时间,keepalive time ,在这段时间内,连接处于非活动状态,开启保活功能的一段,会向对方发送保活探测报文)

      2、尝试次数达到保活探测仍未收到响应则中断连接

  • 相关阅读:
    struts2 之 Action的创建方式
    struts2 之 struts2数据处理
    SuperMap for WebGL 9D 加载平面坐标系三维场景
    SuperMap-WebGL-坐标系及转换说明
    SuperMap -WebGL 实现地球的背景透明并显示自定义图片
    转载: ssh连接上华为云Linux服务器,一会就自动断开
    Arcgis瓦片--js客户端加载
    Arcgis瓦片--数据获取
    转载:Linux服务器Cache占用过多内存导致系统内存不足最终java应用程序崩溃解决方案
    转载-浏览器优化中的2-5-8原则
  • 原文地址:https://www.cnblogs.com/vingLiu/p/10732682.html
Copyright © 2011-2022 走看看