zoukankan      html  css  js  c++  java
  • TCP/IP 协议简单分析

    首先TCPIP是两种不同的协议,它们来七层网络模型中分别在不同的层次,IP协议是网络层的协议,TCP是更高一层的传输层的协议,TCP是建立在IP协议之上的,所以一般把TCPIP连在一起说TCP/IP协议。

    Windows系统的TCP协议栈的数据包默认是1460字节大小,如果一次传输的数据大于这个长度,会把分割成几个长度都不大于1460字节的TCP数据包,每个数据包都会被赋予一个sequnce number(相当于每个数据包的顺序号,凭这个接收端可以知道数据包的前后顺序)

    之后TCP的数据包再被包裹上一层IP的数据的头,形成IP数据包在网上传输(其实最后还要包一层以太网数据包,网络上最终传输的都是以太网数据包)。

    IP数据包到了目的地后,接收端首先把IP数据包的包头去掉,取出TCP的包。接收端每收到一个TCP的数据包都需要返回给发送端一个ACK的数据包告诉发送端已接到此数据包,如果发收端在一定的时间内没有收到某个数据包的ACK响应,会再次发送这个数据包,这样就保证了数据都能被接收端接收到(因特网上丢数据包是很正常的事,如果没有数据包重发机制,很难保证发送的数据都能被接收端完整的收到)。

    每个TCP数据包也是由包头和实际数据组成,包头包含如下主要内容:

    l         Source port2字节)

    发送端的端口号

    l         Destination port2字节)

    接收端的端口号

    TCP包头中只包含双方的端口号,双方的IP地址在IP包的包头,所以在TCP数据包的包头中没有IP地址。

    l         Sequence number4字节)

    数据的顺序号,表示当前数据包中的数据起始顺序号,比如前一个数据包的SEQ为十六进制的:df d5 aa 3d ,数据包的实际数据长度为16字节,那么下一个数据包的SEQ就要在前一个数据包的SEQ基础上加上16,为:df d5 aa 4d

    l         Acknowledgement number4字节)

    接收到对方的某个数据包后的回应顺序号。如果接收到了对方主动发送来的某个数据包,必须要返回对方一个ACK回应数据包,数据包的头部的Acknowledgement number部分根据对方发送数据的SEQ和实际数据长度,返回SEQ + 实际数据长度,表示已经接收到这个数据包。对方收到这个回应,根据数值计算后知道这个数据包已经被对方接收。如果接收不到ACK的回应,就意味着这个数据包已经在网上被丢失,需要重新发送此数据包。

    l         Header length1字节)

    表示TCP数据包的包头长度,整个TCP数据包的长度减包头长度就能得到TCP数据包的实际传送的数据长度。

    l         Flags1字节)

    标志字节,每一位都是一个标志,以下是几个主要标志:

    ACK表示数据包是个ACK回应数据包,表示接收到了对方的某个数据包,具体哪个包由包头的Acknowledgement number部分指示。

    PSH表示这是个有实际数据的包。

    SYN表示这是个建立连接的数据包,通讯双方要通讯,总是由客户端先发送SYN数据包到服务端以建立TCP的连接。

    FIN 表示通讯结束,拆除连接的数据包。

     

    下面描述一次TCP传送数据的完整过程,以一个客户端向服务端发送一些数据为例。

    clip_image001

    Figure 1.一次完整的TCP通讯的过程

     

    1、建立连接

    TCP是面向连接的协议,客户端和服务端要通讯就必须先建立一个连接。首先通讯双方都有地址,就是IP地址加端口号(IP:Port)标识通讯的每一端,客户端的IP:Port跟服务器IP:Port之间就构成一个socket套接字。所谓建立连接就是在客户端的IP:Port跟服务器IP:Port之间建立一个通道,初始化一些通讯的基础设置,以便以后的数据通讯的正常进行。

    1.1.    客户端发送SYN

    总是客户端发起连接,首先客户端发送SYN数据包到服务端以建立TCP连接。

    SYN数据包只有TCP包头,没有实际数据。

    Flags标志字节的SYN位置位,表示是SYN数据包。

    Sequence number由客户端随机生成一个4字节的数据,作为本次连接通讯客户端数据的起始顺序号,以后客户端发往服务端的数据包的Sequence number都在此基础上加上每次传送的实际数据长度依次相加递增,这样根据每个数据包的Sequence number就能判断出数据包的前后顺序,以便接收方根据数据包的顺序拼接数据包。

    1.2.    服务端回应ACKSYN

    服务端收到客户端的SYN后,首先要发送一个ACK数据包给客户端表示收到了这个数据包。

    数据包的Flags标志字节的ACK置位,表示是ACK回应数据包。

    Acknowledgement number 设置为接收到的数据包的 SEQ + 数据包实际长度,因为接收到的SYN的实际数据长度为0,但是TCP协议认为实际长度为0的主动发送的数据长度为1SYN是客户端主动发送的数据包,所以服务端把Acknowledgement number 设置为接收到的数据包的 SEQ + 1

    TCP通讯可以是双向的,一旦建立了连接,服务端也可以向客户端发送数据。

    所以服务端也会向客户端发送一个SYN包,数据包的Flags标志字节的SYN置位,表示是SYN数据包,同时随机生成一个4字节的数据,作为本次连接通讯服务端数据的起始顺序号Sequence number

    实际中,服务端把这两个数据包合并为一个数据包,SYNACK都是置位,Sequence numberAcknowledgement number也同时设置,作为一个数据包发送回客户端。

    1.3.    客户端回应ACK

    客户端收到服务端的SYN数据包后,需要回应一个ACK数据包,表示接收到此数据包。同样ACK数据包的Acknowledgement number 设置为接收到的数据包的 SEQ + 1SYNACK数据包的实际数据长度也是0)。

    2、相互收发数据

    通讯双方建立了连接后,就可以相互进行数据包的传送。

    发送数据的一端,把数据包的Flags标准字节的PSH置位,表示是有实际数据的数据包。

    Sequence number置为前一次的数据包的Sequence number加上前一次数据包的长度。

    如果数据包还兼做ACK包,则把ACK置位,同时设置好Acknowledgement number把数据包发送到对方。

    接收方收到对方主动发送的数据数据包后,一定要回复ACK数据包,如果同时有数据发往对方,可以把实际数据包跟ACK数据包合在一起发送。

    在拆除连接之前,通讯双方可以一直相互发送接收数据,数据的顺序都建立在各自的Sequence number基础上。

    1中,蓝色部分的数据通讯就表示这一阶段。

    3、拆除连接

    双方数据交换完毕,需要拆除连接,结束通讯。

    3.1.    客户端发送FIN

    通讯的一方向另一方发送FIN数据包表示要结束通讯,拆除连接。

    客户端把数据包的Flags标准字节的FIN置位,表示是通讯结束数据包。

    3.2.    服务端返回ACKFIN

    服务端收到客户端的FIN数据包后,先回应一个ACK数据包,然后也发送一个FIN数据包,还是服务端也结束通讯。

    3.3.    客户端回应ACK

    客户端回应ACK表示接收到服务端的FIN数据,双方通讯结束。

    转:http://www.cnblogs.com/chnking/archive/2007/12/28/1017981.html

  • 相关阅读:
    初识python 2.x与3.x 区别
    装饰器
    函数的进阶
    Spring Boot启动问题:Cannot determine embedded database driver class for database type NONE
    22.Spring Cloud Config安全保护
    23.Spring Cloud Bus 无法更新问题(踩坑) Spring cloud config server Could not fetch remote for master remote
    24.Spring Cloud之Spring Cloud Config及Spring Cloud Bus
    Spring Boot整合Spring Data Elasticsearch 踩坑
    项目中Spring Security 整合Spring Session实现记住我功能
    32.再谈SpringBoot文件上传
  • 原文地址:https://www.cnblogs.com/soundcode/p/2133528.html
Copyright © 2011-2022 走看看