文章目录
TCP/IP
4.应用层:程序员写代码的一层(HTTP协议,SSH协议,FTP,DNS)
3.传输层:为了保证两端能够顺利的通讯(TCP/UDP)
2.网络层:用来确定路线和路由选择 (IP协议)
1.数据链路层:相邻结点的数据接收和转换的
Tcp两个对象(客户端,服务器端)
1.服务端:ServerSocket
2.客户端:Socket new Socket(IP,Port) 服务器端
TCP读写数据的重要对象:
1.读BufferedReader socket.getInputStream/读取readLine()
2.写 BufferedWriter writer(“内容\n”)
TCP和UDP的区别:
1.UDP是无连接的,而TCP是有连接的;
2.UDP是不稳定的,TCP是稳定的;
3.UDP是面向数据报的,而TCP是面向数据流;
4.UDP是有接收缓冲区的,没有发送缓冲区;而TCP既有发送缓冲区也有接收缓冲区。
传输层:
端口号:找到应用程序。
端口号:0-65535
端口号分类:
1.知名端口号 0-1023
FTP:21 SSH:22 Telnet:23 DNS:53 HTTP:80 HTTPS:443
2.动态端口号:1024-65535
MySQL:3306 Tomcat:8080
问题:
1.一个端口号可以被多个程序使用吗?
不可以
2.一个程序可以绑定多个端口号吗?
可以。
人和电话号码的关系,一个手机号码只能归属一个人,但一个人可以拥有多张电话号码
UDP协议
*16位UDP长度=UDP头部长度(8个字节)+数据长度
UDP一个包的最大理论长度=2的16次方=65536/1024=64KB
*效验和是用来要确定数据在传输过程中是否被篡改,也就是用来判断数据的正确性的。
如何判断的?
假设数据是以MD5进行校验和的计算,那么原始的数据会先进行MD5得到一个值,把这个值存储在16 位的校验和当中;接收端接收到内容之后,按照通过的规则加密数据得到一个校验和,用这个计算出来的校验和和UDP头中的16位校验和对比,如果相等数据是正确的。
面试题:如果UDP编程时的数据大小大于64KB会怎样?
1.在应用层进行数据包的拆分和组合。在应用层就是让程序去处理UDP大包,把大包分成多个子包。
2.大于64kB 不处理,交给TCP/IP协议去处理,他会在网络层进行分包和组包。交给网络层存在丢包的风险。(不用) 有缺点:一个包丢失,那么整组包都会丢弃
UDP的使用场景:DNS(域名解析服务)【域名和IP的映射】
全双工:发送端或接收端,既能发送消息又能接收消息
半双工:发送端只能发送消息,不能接收消息;接收端只能接收消息,不能发送消息
UDP:全双工
TCP:全双工
UDP使用注意事项
我们注意到, UDP协议首部中有一个16位的最大长度. 也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部).
然而64K在当今的互联网环境下, 是一个非常小的数字.
如果我们需要传输的数据超过64K, 就需要在应用层手动的分包,多次发送,并在接收端手动拼装
基于UDP的应用层协议
NFS: 网络文件系统
TFTP: 简单文件传输协议
DHCP: 动态主机配置协议
BOOTP: 启动协议(用于无盘设备启动)
DNS:域名解析协议
当然, 也包括你自己写UDP程序时自定义
TCP协议:
TCP协议段格式
URG:当是1时表示紧急指针
ACK:是否是确认应答消息,如是1表示确认是应答消息
PSH:用来表示是否立即从缓冲区取走数据
RST:复位标识。
SYN:同步序列号标识。(TCP连接时候使用)
FIN:结束序列号标识。(TCP断开连接时候使用)
16位效验和:用来确定当前数据是否是正确的。
缺点:太繁琐,在信息传递过程中占有太多的带宽。
确认应答可能带来的问题:
1.发送消息丢失
2.ACK丢失了
内核:会自动做消息去重
超时重传的策略:
策略1:发送不会以固定的频率发送。策略1采用的是悲观的策略,如果第一次消息发送失败了,那么大概率第二次发送消息也会失败,所以TCP会以指数级超时时间增长的频率来发送消息
第一次超时重发时间间隔:500MS
第二次超时重发时间间隔:2500MS
第三次超时重发时间间隔:4500MS策略2:如果经历了一定次数的重试次数,消息还没有应答,那么就会停止发送。
**3次握手(3次通讯)syn/syn+ack/ack
三次握手是为了验证收发两端的收发能力(双工)
面试:两次握手可以吗?
不行,第二次握手时只能证明客户端的发送能力和服务器端的接收能力
ESTABLISHED:表示3次握手已经完成,可以进行数据的传输了
****4次挥手(4次通讯)**fin/ack/fin/ack
四次挥手:为了确保发送端和接收端能够正常关闭。
面试:3次挥手可以吗?
有可能可以。如果没有待结束的任务,两次挥手就可以合并。(捎带应答)对应到程序:接收缓冲区没有数据了,那么就可以直接关闭连接。
为什么TIME_WAIT 要等待2 MSL(最大超时时间)?
2 MSL=ACK最大超时时间(1 MSL)+对方发送给你消息的一个最大等待时间(1 MSL)。
1 MSL Linux默认是500
如果发现服务器端存在大量的CLOSE_WAIT说明程序有问题?
答:程序的BUG,程序中没有调用colse()主动关闭连接。
窗口大小指的是无需等待确认应答而可以继续发送数据的最大值.
操作系统内核为了维护这个滑动窗口, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉;
情况一:数据包已到达,ASK丢失。
ACK=6001的含义:并不是告诉主机A,已经成功收到了5001~6000,而是告诉主机A,我已经成功接收到0~6001
ACK返回的是当前(主机B-右边)接收缓冲区的下一个值(最大连续值)。
当前面的数据被正常补齐之后,返回的ACK是最大值,这种机制叫“快重传”。
16位窗口大小:
以结果(接收缓冲区的大小)为导向进行数据的传递
16位的窗口大小不是滑动窗口的大小,因为滑动窗口大小是固定的,所以不需要传来传去。他记录的是接收缓冲区窗口的大小,这个是动态改变的。
如果16位滑动窗口为0,那么发送端就不会发消息给接收端
TCP会以固定的频率发一个检测包,用来检测接收区的空间大小的,当接收缓冲区不为0时,那么消息就会恢复发送。
** 拥塞控制以当前网络环境的拥塞程度为导向
根据当前时间的网络来动态调整收发的频率就叫拥塞控制
刚开始初始发送一个包,如果可以正常接收就会以指数型增加发送的数量包数量,一直增加到流量控制的最大值之后,就会从指数型增长变成线性增长,一直进行收发,直到出现大量数据包丢失的时候:1.将发送的数量修改成1;
2.将流量控制的最大值设置成当前丢失的值/2;继续进行发包,一直循环直到成功。 等个过程叫慢开始。
延迟应答策略:
1.每个一段时间(固定时间)延迟应答一次,一定程度加速发送消息的速度
2.每隔N次(2次)延迟应答一次
延迟应答注意事项:
延迟时间(200ms)的时间一定要小于超时重传的时间(500ms).
问题:
TCP 面向数据流:流没有边界,可能会造成沾包和半包。
沾包:
半包:
沾包和半包都是用来指得到的数据不是预期的数据(要么多要么少)。
沾包半包解决方案:
1.使用\n作为流的结束符,这样流就有边界了,就能正常收发消息了
2.每次发送固定大小的流信息,这样就能确定每个数据边界,也就能正常的收发消息了。
TCP异常情况:
1.进程终止: 进程终止会释放文件描述符, 仍然可以发送FIN. 和正常关闭没有什么区别.
2.机器重启: 和进程终止的情况相同.
3. 机器掉电/网线断开: 接收端认为连接还在, 一旦接收端有写入操作, 接收端发现连接已经不在了, 就会进行 reset. 即使没有写入操作,TCP自己也内置了一个保活定时器, 会定期询问对方是否还在. 如果对方不在, 也会把连接释放.
4 另外, 应用层的某些协议,也有一些这样的检测机制. 例如HTTP长连接中, 也会定期检测对方的状态. 例如 QQ, 在QQ断线之后,
也会定期尝试重新
TCP异常情况处理
1.可挽救:电脑重启或者结束进程的时候,他会发送FIN请求,和正常关闭TCP是没有什么区别的
2.不能挽救:电脑断电/网线中断:TCP报活定时器,会定时检测对方是否在线,如果检测的结果没有任何响应,说明已经掉下,直接释放连接。
TCP总结
保证稳定性:
1.确认应答
2.超时重传
3.连接管理----三次握手,四次挥手
4.流量控制
5.拥塞控制
保证性能:
1.滑动窗口
2.延时应答
3.捎带应答
TCP和UDP的区别:
1.UDP是无连接的,而TCP是有连接的;
2.UDP是不稳定的,TCP是稳定的;
3.UDP是面向数据报的,而TCP是面向数据流;
4.UDP是有接收缓冲区的,没有发送缓冲区;而TCP既有发送缓冲区也有接收缓冲区。
5.UDP和TCP使用场景不同,如果对稳定性要求比较高,应使用TCP,如果对消息丢失不敏感,要求性能比较高,使用UDP
TCP,UDP适用场景
TCP协议提供可靠的服务,
UDP协议提供高效率的服务。
高可靠性的TCP服务提供面向连接的服务,主要用于一次传输大量报文的情形,
如文件传输,远程登录等;
高效率的UDP协议提供无连接的数据报服务,用于一次传输少量的报文。
即使发生传输错误,也可以重新传输并且不会为此付出多少代价。
TCP提供的是面向连接的、可靠的数据流传输,可避免数据传输错误。
面向连接的协议在任何数据传输前就建立好了点到点的连接。
而UDP提供的是非面向连接的、不可靠的数据流传输。当一个UDP数据包在网络中移动时, 发送过程并不知道它是否到达了目的地,除非应用层已经确认了它已到达的事实。
当数据传输的性能必须让位于数据传输的 完整性、 可控制性 可靠性时, TCP协议是当然的选择。
当强调传输性能而不是传输的完整性时, 如:音频和多媒体应用, UDP是最好的选择。
在数据传输时间很短,以至于此前的连接过程成为整个流量主体的情况下 UDP也是一个好的选择 ,如:DNS交换。把SNMP建立在UDP上的部分原因是设计者认为当发生网络阻塞时, UDP较低的开销使其有更好的机会去传送管理数据。
总结 tcp 提供可靠的服务 若强调 完整性 可靠性可控性 选择tcp
udp 提供高效的服务 若强调 传输性能 选择udp
面试题:如何使用UDP实现稳定的消息传输
答:在应用层参考TCP实现稳定性的特性来设计UDP
保证稳定性 1.确认应答
2.超时重传
3.连接管理
4.流量控制
5.拥塞控制