我是靠谱客的博主 干净悟空,最近开发中收集的这篇文章主要介绍TCP/IP,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录​​​​​​​

1.传输层的UDP

职责:在主机可以和主机通信的基础上,实现了进程与进程的通信

UDP的特点:(寄信一样,想寄多少寄多少)

基于udp的应用层协议

2.传输层TCP协议:Transmission Control Protocol 传输控制协议 (重点)

TCP的三次握手(handshake)的过程

从标志位的角度

从序列号的角度:

从TCP状态变更的角度

Linux命令行的介绍

抓包wireshark的抓包命令


1.传输层的UDP

职责:在主机可以和主机通信的基础上,实现了进程与进程的通信

UDP协议的包头添加的封装(包括解包和分用即可)

解包就是把这8个字节去掉,交给应用层。

校验和(checksum):防止数据错误的机制(类似于hash的算法)采用的是CRC算法

包头:header

有效数据(负荷):payload

 

 udp协议首部中有一个16位的最大长度,也就是说一个udp能传输的数据的最大长度是64k(包含udp首部)????/???????


发送

 ps:UDP协议栈内部没有缓冲区

udp只有接收缓冲区,没有发送缓冲区

udp的socket既能读,也能写,这个概念叫做全双工(既可以发也可以收)


接收


UDP的特点:(寄信一样,想寄多少寄多少)

1.不可靠 (只管发,对方有没有收到,不知道)

2.无连接(不需要建立连接)

3.数据是面向数据报文的(我发了什么对方就会收到什么,不会多发或者少发)


抓包

 

 两个数字是一个字节,蓝色的是8个字节,是udp的报头部分

这个采用的是大端模式

大端  27 0f直接翻译,如果是小端是0f 27

 变为十进制就是:源端口号:9999

目的端口号:8080

长度:36(数一下,刚刚好)


基于udp的应用层协议

NFS:网络文件系统

TFTP:简单文件传输协议(比FTP(文件传输协议)使用简单,但是FTP使用TCP传输)

DHCP:动态主机配置协议

BOOTP:启动协议(用于无盘设备启动)

DNS:域名解析协议


笔试题

选C  数据只是被发送出去了,不知道后续会怎么样


2.传输层TCP协议:Transmission Control Protocol 传输控制协议 (重点)

职责:1.进程 to 进程  2.可靠 (承诺的是可靠,但是从来没有承诺过安全)


TCP包头:如何进行解包,进行分用

 tcp首部包括选项,所以是变长的

所以在首部长度字段中写入整个包头的长度,做解包用的。

以四个字节为单位的,存1表示长度4个字节,2表示长度8个字节,而一个字节8个bit

tcp校验和与udp类似:


TCP的可靠性

1.tcp会尽自己最大的努力,将数据发送给对方

2.如果真的遇到发送不过去的情况,tcp至少会告诉发送进程,数据发送失败了

3.保证不会收到错误的数据(通过checksum)

4.tcp能保证收到的数据一定是有序的,按照发送进程发送时的t)

(发送的数据可能和接受的顺序在接收后可能是乱序的,udp没有做有序的保证,但是tcp保证了)

5.tcp会根据对方的接收能力和网络线路的承载能力,进行流量的控制


TCP保证可靠性的机制

1.确认-应答机制:接收方(对方的TCP)有责任对收到的信息进行确认(ackonwledge)应答。

问:如果一次性收到多条数据,怎么知道我应答的是哪条数据?

答:所以应该对数据做一定的编号(序列号 sequence number SN),只要明确哪个收到,就是这个数据收到了。

2.确认段(segment):一份数据既可以当发送的数据,也可以起到确认的角色

可以省略确认ack=1


TCP 各自发送的SN、ASN都是独立的(序列号是独立的)

 ASN(期望下一个发送的序列号)

SN  本次数据的第一个字节的编号


站在发送端:

当我发送一份数据,没有收到应答时,可能发送了什么?

可能的情况:a.对方没有收到

b.对方收到了,只是应答没有发送过来

遇到这样的情况,解决办法:(超时重传机制)

1.不应该无限期的等下去(超时timeout机制)

2.然后重新发送数据


对于a的情况我重新发送数据,接收端等同于第一次收到这个数据,对接收端的主机没有影响

对于b的情况,只是应答被丢失,那么我重新发送数据,接收端就收到了2次数据,所以接收端要有能力进行去重操作。

接受端主机能否判断出数据有重复?

答:根据序列号来判断这个数据是否收到过,然后再判断是否接收这些数据,接收哪些数据。

所以TCP在发送数据的时候。发送端不需要在意没有收到应答是什么原因,只要超时重传即可。真的接收端收到了重复的数据,直接丢掉即可。

那么超时重传是无限制的吗?

不是,超过一定上限(具体上限操作系统可以配置),就放弃,认为本次数据线路出现问题了。

1.TCP会关闭本次连接

2.TCP会通知进程(java中,采用异常方式抛出,是IOException的子异常)

3.TCP会发送一个reset segment 出去

超时时间的设置:

超时时间一般不是固定的长度,大多数采用的是逐步变长的长度。

10s-->20s-->40s-->80s

站在进程角度思考,向一个有问题的TCP线路中发送数据,请问多久之后,进制知道线路出问题了。

10+20+40+80s之后才会发现

作为TCP的发送方,经过一段时间之后,可以知道线路有问题的,但是TCP的接收方,无法得知线路是有问题的,无法区分对方是没有数据发送还是发送失败了。


所以确认应答机制(数据编号机制+超时重传机制)

3. 连接(Connection)管理(Management)

1.TCP有没有发送缓存区(send buffer)

有,发送数据之后不可以直接丢弃,不可以,可能要重发。所以,至少需要一个地方保存这些数据。

2.TCP有接收缓冲区。

3.TCP需要维护好发送时的序号  SN=x,才可以用于发送时填充SN字段。

4.TCP得维护已经接收的数据的序号 ASN=y;维护之后才可以进行去重。

5.维护状态信息


进去操作系统,只有一个TCP协议栈,并不是每一个TCP都有一个协议栈。

在TCP协议栈的角度,连接是属性的集合,把关键的属性抽象出来形成了一个连接。

还维护了整体的Map,也是共用的。


为什么需要进行建立连接的过程?

1.必须确认对方存在,才能可靠的传输。

2.交换一些必要的数据。

SN不是直接从1开始的,要不然安全性不高,会双方各自随机SN生成,随后需要交换。


在正式通信之前,需要一个阶段

1.确认对方在线

2.同步(synchronize)一些基本信息

a.2,3基本是同一时间发生的

b.TCP的segment可以既承载数据,又承载应答的职责

结论:2,3是会被合并的


TCP的三次握手(handshake)的过程

从标志位的角度

 

segment的种类:

发送segment

确认segment

同步信息(握手阶段使用)segment

挥手segment


从序列号的角度:


从TCP状态变更的角度

建立连接的过程

CLOSED:虚拟状态(最原始的状态)

LISTEN:被动连接方(服务器在监听,但是还没有连接出现),服务器已经启动,但没有真正的连接建立

SYN_RCVD:收到了snyc

SYN_SENT:sync已经发送了

虚线是被动连接方,实线是主动连接方走的路。

 


而我如何知道当前处于什么阶段?

根据状态。

TCP的状态(表示当前连接目前的状况)


TCP协议栈逻辑:是典型的时间驱动型逻辑,也就是戳一下动一下

 时钟用来控制超时的。

所以上面的程序被动打开是应用层搞出来的事情

程序发送数据是应用层搞出来的事

收到SYN是网络层搞出来的(网络层从下层收到了)


被动连接方:服务器部分代码截图

主动连接方

 


Linux命令行的介绍

如何查看端口是否存在 netstat 命令

# netstat  -nlpt  n把所有按照数字形式显示,l是只看listen状态的TCP

p把进程id打出来  t 是只看tcp 

 然后再看一下4075718进程是谁?

# ps aux | grep 

 客户端

netstat -napt | grep 8080

看全部的状态,但是只看8080这个端口的

 第二条就是真正建立连接,是established状态,

上面的10.105.52.100:8080  是服务器的ip地址以及端口

117.22.136.214:18687  是本机的公共ip地址,以及端口 

客户端抓包:

抓包wireshark的抓包命令

ip.addr == 182.254.132.183 && tcp.port == 8080

 客户端没有发送数据,所以抓到的包属于三次握手

第一条(从客户端到服务器),source:源ip  destination:目的ip  协议  TCP  长度就是应用层的长度,segment长度还包括tcp header 的长度。

Info  从58533 到 8080 标准位SYN,序列号为 0,Len:为0,因为没有携带数据

  MSS    WS

第二条(从服务器到客户端):所以端口号反过来了,从58533到8080,标志位为SYN,ACK

序列号为 0(这是相对的),

第三条,只有一个ack

因为我们没有发送数据,所以没有应用层的数据

所以这里前俩条为应用层的数据帧,然后是 网络程,然后是传输层

把传输层展开

 

蓝色的部分就是 包头部分  

0xe4a5   就是源端口号  58533

相对的序列号为0 ,真实的虚拟号为294035483(意思是序列号是随机生成的,并不是从零开始的)

Acknowledgment Number : 0   确认序列号为0

Acknowledgment Number(raw):0   

所以第一行的四个,都是零 

打开flag(标志位)

 

 可以看到除了SYN被设置,其他的都没有被设置

服务器那一条的flag

 SYN和ACK都被置为1

 序列号是自己生成的

而 刚才sequence number 为294035483,现在Acknowledgment Number +1


整个前面俩个包,

三次握手的过程在这俩次打印之间 

 

最后

以上就是干净悟空为你收集整理的TCP/IP的全部内容,希望文章能够帮你解决TCP/IP所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部