资讯专栏INFORMATION COLUMN

Linux常见信号和网络传输层知识分享

Tecode / 2187人阅读

摘要:控制,进程收到该信号退出时会产生文件,类似于程序错误信号。执行了非法指令。调用函数产生,将会使程序非正常结束。它与的区别在于后者是由于对合法地址的非法访问触发编程中过程中遇到不慌,下面列举一些网络传输层知识。

下面列举一些Linux中常见的信号,平时做开发经常遇到的。

SIGINT:程序终止信号。当用户按下CRTL+C时通知前台进程组终止进程。
SIGQUIT:Ctrl+控制,进程收到该信号退出时会产生core文件,类似于程序错误信号。
SIGILL:执行了非法指令。通常是因为可执行文件本身出现错误,或者数据段、堆栈溢出时也有可能产生这个信号。
SIGTRAP:由断点指令或其他陷进指令产生,由调试器使用。
SIGABRT:调用abort函数产生,将会使程序非正常结束。
SIGBUS:非法地址。包括内存地址对齐出错。比如访问一个4个字长的整数,但其地址不是4的倍数。它与SIGSEGV的区别在于后者是由于对合法地址的非法访问触发


编程中过程中遇到不慌,下面列举一些网络传输层知识。

端口号范围划分
0-1023:知名端口号,HTTP,FTP,SSH等这些广为使用的应用层协议,他们的端口号都是固定的
1024-65535 操作系统动态分配的端口号,客户端程序的端口号,就是由操作系统从这个范围分配的。

认识知名端口号
SSH服务器,使用22端口
ftp服务器,使用21端口
Telnet服务器,使用23端口
http服务器,使用80端口
https服务器,使用443

netstat
n拒绝显示别名,能显示数字的全部转化为数字
l 仅列出有在listen的服务状态
p 显示建立相关连接的程序名
t 仅显示tcp相关信息
u 仅显示udp相关信息
a 显示所有的选项,默认不显示listen相关
pidof查看服务器的进程ID

UDP协议
16位源端口号 和16位目的端口号
16位UDP长度 和16位校验和
16位UDP长度,表示整个数据报(UDP首部+UDP数据)的最大长度
如果校验和出错,就会直接丢弃

UDP的特点
无连接:知道对端的IP和端口号就直接进行传输,不需要建立连接
不可靠:没有确认机制,没有重传机制,如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息
面向数据报:不能够灵活的控制读写数据的次数和数量

面向数据报
应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并

UDP的缓冲区
UDP没有真正意义上的发送缓冲区,调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作
UDP具有接受缓冲区,但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致,如果缓冲区满了,再到达的UDP数据就会被丢弃
操作系统把数据给网卡(硬件),然后触发中断(大端CPU当前正在执行的东西)
UDP使用注意事项
UDP协议首部有一个16位的最大长度,也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部)
如果我们需要传输的数据超过64K,就需要在应用层手动的分包,多次发送,并在接收端手动拼装

TCP协议
16位源端口号,16位目的端口号
32位序号
32位确认序号
4位首部长度,保留6位状态码,16位窗口大小
16位校验和,16位紧急指针

源/目的端口号:表示数据从哪个进程来,到哪个进程去

32位序号/32位确认信号:序号有三重作用,我就列三条分别说明吧
有了序列号,我们就可以将字节流的数据一一编号,然后我们可以保证数据的顺序一致
序列号还可以去重,当确认报文丢失,服务器会以为发送的数据已经收到,但是客户端一直无法收到ACK,然后客户端就会不断发送重复报文,数据就会重复,但是有了序号服务器就会知道那些数据多发了,然后用相应的机制进行去重
32位确认序号就是每当序号比如1-1000收到,然后确认序号就设置为1001,保证之前的报文绝对不出错
4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节),所以TCP头部最大长度是15*4 =60;

6位标志位
URG:紧急指针,这是优先级,判断那段报文优先发送
ACK:确认号是否有效
PSH: 提示接收端应用程序立刻把从TCP缓冲区把数据读走
RST: 对方要求重新建立连接,我们把携带RST标识的称为复位报文段(告知客户端建立连接失败,重新链接一下)
SYN:请求建立连接,我们把携带SYN标识的称为同步报文段
FIN:通知对方,本端要关闭了,我们称携带FIN标识的位结束报文段(当客户端长时间没有响应(发送数据报时)服务器任务客户端挂掉了,就会断开连接)因为服务器要维持连接的话需要消耗资源,对于这种暂时不用的资源,当然是选择挂掉,待他再次响应时重新进行连接)
16位窗口大小:就是发送方的接收缓冲区的大小,在进行三次握手的时候,服务器会和客户端协商窗口大小,得知对方的接收能力从而控制发送速度来避免出现阻塞

确认应答(ACK)机制
当我们启动服务器,然后启动客户端,然后关闭服务器,再立刻运行服务器,就会出现问题,原因如下

  • 虽然server的应用程序终止了,但是TCP协议层的连接并没有完全断开,因此不能再次监听同样的server端口
  • TCP协议规定,主动关闭连接的一方要处于TIME_WAIT状态,等待两个MSL的时间才能回到CLOSED状态
  • 我们使用ctrl+C终止了服务器,所以服务器是主动关闭的一方,在TIME_WAIT期间仍然不能再次监听同样的服务器端口
  • MSL在RFC1122中规定为两分钟,操作系统实现不同,Centos7默认配置的值是60s
  • 可以通过 cat/proc/sys/net/ipv4/tcp_fin_timeout 查看msl值

为什么要等待两个MSL时间
MSL是TCP报文的最大生存时间,因此TIME_WAIT持续存在2MSL的话,可以保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启,可能会收到来自上一个进程的迟到的数据,但是这种数据很可能是错误的)
同时也是在理论上保证最后一个报文可靠到达(假设最后一个ACK丢失,那么服务器会重发一个FIN,这时虽然客户端的进程不在了,但是TCP的连接还在,仍然可以重发LAST-ack);
当连接数量很大,虽然存在时间很短,如果服务器主动关闭连接,就会造成大量的TIME_WAIT连接,导致服务器的端口不够用,无法处理新的连接,想一想,每个都要等两分钟,那么效率会很低

使用setsockopt()设置socket描述符的选项SO_REUSEADDR为1,表示允许创建端口号相同DNAIP地址不同的多个socket描述符
在server的socket()和bind()调用之间插入

int opt =1;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

一发一收的方式性能较低,那么我们一次发送多条数据,就可以大大提供性能(其实是将多个短的等待时间叠加在一起)
窗口大小就是无需等待确认应答而可以继续发送数据的最大值
收到第一个ACK之后,滑动窗口就开始向后移动,继续发送数据
操作系统为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有那些数据没有应答,只有确认应答过的数据,才能从缓冲区删除
窗口越大,则网络的吞吐率就越高

超时重传机制
主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B
如果主机A在一个特定时间间隔内没有收到来自B发来的确认应答,就会进行重发

如果是B发过来的确认应答丢掉了,那么客户端就会以为数据没有发送过去,然后就会一直发送知道收到ACK为止。主机B收到很多重复的数据,那么TCP协议需要能够识别出那些包是重复的包,并且把重复的丢弃掉,就可以利用序列号进行去重工作

超时时间如何确定?
在最理想的情况下,找到一个最小的时间,保证确认应答一定能在这个时间内返回
根据网络状况会有差异
如果设置的太长,会影响整体的重传效率
设置太短,就会频繁发送重复的包

TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间
Linux的超时以500ms为一个单位,如果重发一次仍然收不到应答,那就*2,一次类推,累积到一定的重传次数之后,TCP认为网络或者对端主机出现异常,强制关闭连接
如果发了10000个包,只是丢了五六个,默认重传,但是如果丢了八九千个,那肯定是网络出现了故障,果断断开连接

快重传机制
当某一段报文丢失之后,发送端会一直收到1001这样的ACK,如果发送端连续3次发送同样的1001的应答,就会将对应的数据重新发送
这个时候接收端收到了1001之后,再次返回的ACK就是7001了(因为2001-7000)接收端之前就已经收到了,被放到接收端操作系统内核的接收缓冲区内

流量控制
接收端处理数据的速度是有限的,如果发送端发的太快,导致接收端的缓冲区被放满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等一系列的连锁反应
因此TCP支持根据接收端的处理能力,来决定发送端的发送速度
接收端将自己可以接收的缓冲区大小放入TCP首部中的窗口大小字段,通过ACK端通知发送端,窗口大小字段越大,说明网络的吞吐量越高
接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送方
接收端收到这个窗口之后,就会减慢自己的发送速度
如果接收端缓冲区满了,就会将窗口设置为0,这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

拥塞控制
拥塞是由于网络状况不好,大量丢包重发导致的。如果网络不好,但是发送速度不变,就会出现网络拥塞,因此TCP引入一个慢启动机制,先发少量的数据,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据
发送开始的时候,定义拥塞窗口大小为1,每次收到一个ACK应答,拥塞窗口加1
,每次发送数据报的时候,将拥塞窗口和接收端主机反馈的窗口大小作比较,取较小的值作为实际发送的窗口,这样一定可以避免面数据传输拥塞问题。
虽然叫做慢启动,但是那只是刚开始增长比较慢,到后面会呈现指数增长,增长速度太快了,为了改变这种状况,我们需要知道下面的原理

  • 为了不增长的那么快,我们不能让拥塞窗口单纯的加倍
  • 此处引入一个慢启动的阈值
  • 当拥塞窗口超过这个阈值时,不再按照指数增长,而是按照线性增长
  • 当TCP开始启动的时候,慢启动阈值等于窗口最大值
  • 在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置为1

出现少量的丢包现象时,我们出发超时重传机制,但是出现大量的丢包时,我们就认为是网络拥塞引起的。
TCP的这套机制是为了在保证速度的同时保证数据传输的安全性和可靠性。

延迟应答
如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小
窗口越大,网络吞吐量就越大,传输效率就越高,我们的目标是在保证网络不拥塞的情况下尽量提高传输效率。
但是不是每个包都能延时应答,应该是隔几个包有一次应答,当超过最大延迟时间就应答一次
延迟应答的等待时间也是和网络状况有关的,因此是动态变化的。

粘包问题
TCP的报文是按照顺序传输过来的
站在应用层的角度,看到的知识一串连续的字节数据
当应用程序看到了这么一连串的字节数据,就不知道从那部分开始到哪个部分是一个完整的应用层数据包

为了避免粘包问题,我们需要明确两个包之间的边界
对于定长的包,,保证每次都按照固定大小读取即可
对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置
对于变长的包,还可以在包和包之间使用明确的分隔符

对于UDP来说不存在粘包问题
UDP,如果还没有上层交付数据,UDP的报文长度仍然在,同时,UDP是一个一个把数据交付给应用层,就有很明确的数据边界
站在应用层的角度,使用UDP时,要么收到完整的UDP报文,要么不收不会出现半个的情况

TCP异常情况
进程终止:进程终止会释放文件描述符,仍然可以发送FIN,和正常关闭没有什么区别
机器重启:和进程终止的情况相同
机器掉电/网线断开:接收端认为连接还在,一旦接收端有写入操作,接收端发现连接不在了,就会进行reset,即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在,如果对方不在,也会把连接释放

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/125999.html

相关文章

  • 深度学习的时间序列模型评价

    摘要:技术总言这次主要说最近发展的无监督特征学习和深入学习,其对于时间序列模型问题的评价。建模连续数据的传统方法包括从假定时间序列模型参数的估计,如自回归模型和线性动力系统,和著名的隐马尔可夫模型。此外,时间序列对时间变量有明显依赖性。 技术总言:这次主要说最近发展的无监督特征学习和深入学习,其对于时间序列模型问题的评价。这些技术已经展现了希望对于建模静态数据,如计算机视觉,把它们应用到时间序列数...

    zhaochunqi 评论0 收藏0
  • 神经网络基础

    摘要:要学习深度学习,那么首先要熟悉神经网络,简称的一些基本概念。网络径向基函数网络是一种单隐层前馈神经网络,它使用径向基函数作为隐层神经元激活函数,而输出层则是对隐层神经元输出的线性组合。 阅读目录1. 神经元模型2. 感知机和神经网络3. 误差逆传播算法4. 常见的神经网络模型5. 深度学习6. 参考内容目前,深度学习(Deep Learning,简称DL)在算法领域可谓是大红大紫,现在不只是...

    starsfun 评论0 收藏0
  • 【2021版】想要专升本你不得不看的全干货_吐血整理_专升本_计算机文化基础(四)

    摘要:由于屏蔽层的作用,同轴电缆有较好的抗干扰能力。表示层了解即可表示层主要为上层用户解决用户信息的语法表示问题,其主要功能是完成数据转换数据压缩和数据加密。协议实际上是一组协议,是一个完整的体系结构。 ...

    Genng 评论0 收藏0
  • 吴恩达新成果:机器学习模型能比医生更精确诊断心律失常

    摘要:由吴恩达领导的斯坦福大学机器学习小组,研发出一种新的深度学习算法,可以诊断种类型的心律失常。吴恩达表示,机器学习模型可以比专家更较精确的诊断心律失常。这项研究可能是机器学习彻底改变医疗行业的标志之一。 由吴恩达领导的斯坦福大学机器学习小组,研发出一种新的深度学习算法,可以诊断14种类型的心律失常。吴恩达表示,机器学习模型可以比专家更较精确的诊断心律失常。这项研究可能是机器学习彻底改变医疗行业...

    rollback 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<