1. TCP UDP 区别,分别适用什么场景?
2. TCP怎么保证可靠传输
面向字节流,超时重传,应答机制,滑动窗口,拥塞控制,校验等
1、确认和重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就重传。
2、数据校验
3、数据合理分片和排序:
UDP:IP数据报大于1500字节,大于MTU.这个时候发送方IP层就需要分片(fragmentation).把数据报分成若干片,使每一片都小于MTU.而接收方IP层则需要进行数据报的重组.这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,接收方便无法重组数据报.将导致丢弃整个UDP数据报.
TCP会按MTU合理分片,接收方会缓存未按序到达的数据,重新排序后再交给应用层。
4、流量控制:当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。
5、拥塞控制:当网络拥塞时,减少数据的发送。
3. TCP 三次握手和四次挥手(详细),TCP握手以及每一次握手客户端和服务器端处于哪个状态(11种状态)
4. TCP中断连接时为什么要有time_wait状态?TIME_WAIT的意义(为什么要等于2MSL)
MSL叫做最长报文段寿命。
(1) 为了保证A发出的最后一个ACK报文段能够到达B
(2) 防止“已失效的连接请求报文段”出现在本连接中
5. TCP连接的建立为什么是三次握手而不是两次握手?为什么客户端最后还要发送一次确认呢
如果仅两次连接可能出现一种情况:客户端发送完连接报文(第一次握手)后由于网络不好,延时很久后报文到达服务端,服务端接收到报文后向客户端发起连接(第二次握手)。此时客户端会认定此报文为失效报文,但在两次握手情况下服务端会认为已经建立起了连接,服务端会一直等待客户端发送数据,但因为客户端会认为服务端第二次握手的回复是对失效请求的回复,不会去处理。这就造成了服务端一直等待客户端数据的情况,浪费资源。
6. TCP为什么挥手是四次而不是三次
(1)TCP是全双工的,它允许两个方向的数据传输被独立关闭。当主动发起关闭的一方关闭连接之后,TCP进入半关闭状态,此时主动方可以只关闭输出流。
(2)之所以不是三次而是四次主要是因为被动关闭方将"对主动关闭报文的确认"和"关闭连接"两个操作分两次进行。
(3)对主动关闭报文的确认是为了快速告知主动关闭方,此关闭连接报文已经收到。此时被动方不立即关闭连接是为了将缓冲中剩下的数据从输出流发回主动关闭方(主动方接收到数据后同样要进行确认),因此要把"确认关闭"和"关闭连接"分两次进行。
7. 怎么解决TCP的粘包问题?TCP/IP的分片粘包过程
(1)产生黏包的原因?
(2)如何处理粘包、拆包
8. TCP传输数据时,如果有一个确认报文丢失了,也不一定会引起与该确认报文段对应数据的重传。说明理由
尚未重传便收到了对更高序号的确认。
9. 有没有不是因为拥塞控制而引起的分组丢失的情况?如果有,举例。
(1)IP数据包在数据传输的时候需要分片,但其中一个未能及时到达终点,而终点组装IP数据包已经超时,因而只能丢弃该数据报。
(2)IP数据报已经到达终点,但是终点的缓存没有足够的空间存放此数据
(3)数据报在转发过程中经过一个局域网的网桥,但是网桥在转发该数据报的帧的时候没有足够的差错空间而丢弃。
10. 流量控制的介绍,采用滑动窗口会有什么问题(死锁可能,糊涂窗口综合征)?
(1)介绍
流量控制是通过滑动窗口为了控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。例如将窗口字段设置为 0,则发送方不能发送数据。
(2)问题
(3)解决方法
让接收方等待一段时间,使得接受缓存区已有足够的空间容纳一个最长的报文段,或者等待接收缓存已经有了一半的空闲空间。有这两种情况之一,就发送确认报文。
11. TCP拥塞控制详解,以及算法名字?(极其重要)
cwnd: 拥塞窗口
ssthresh: 慢开始门限
发送方让自己的发送窗口等于拥塞窗口
当cwnd< ssthresh,cwnd以慢开始的方法指数增长;
当cwnd> ssthresh,cwnd以拥塞避免的方法线性增长。
新ssthresh=原来的ssthresh/2
快重传:收到3个同样的确认就立刻重传,不等到超时;
快恢复:cwnd不是从1重新开始,从上一个ssthresh/2+3开始
总体:加法增大AI,乘法减小MD
12. 拥塞控制和流量控制的区别,发送窗口的大小取决于流量控制还是拥塞控制?
13. UDP报文大小最多是多少
(1)以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的. 这个1500字节被称为链路层的MTU(最大传输单元)。并不包括链路层的首部和尾部的18个字节.
所以,事实上,这个1500字节就是网络层IP数据报的长度限制. 因为IP数据报的首部为20字节,所以IP数据报的数据区长度最大为1480字节. 而这个1480字节就是用来放TCP传来的TCP报文段或UDP传来的UDP数据报的. 又因为UDP数据报的首部8字节,所以UDP数据报的数据区最大长度为1472字节. 这个1472字节就是我们可以使用的字节数。
(2)当我们发送的UDP数据大于1472的时候会怎样呢?
这也就是说IP数据报大于1500字节,大于MTU.这个时候发送方IP层就需要分片。把数据报分成若干片,使每一片都小于MTU.而接收方IP层则需要进行数据报的重组。这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,接收方便无法重组数据报.将导致丢弃整个UDP数据报。
14. UDP如何实现可靠传输?
传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。
最简单的方式是在应用层模仿传输层TCP的可靠性传输。下面不考虑拥塞处理,可靠UDP的简单设计。
15. nagle算法了解吗?
若发送应用进程把要发送的数据煮个字节的送到TCP的发送缓存,则发送发就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢的时候,用这样的方法可以明显的减少所用的网络带宽。nagle算法还规定,当到达的数据以达到发送窗口大小的一半或已到达报文段的最大长度时,就立即发送一个报文段。这样可以有效地提高网络的吞吐量。
16. TCP三次握手,三次握手中第二次握手的SYN和ACK可不可以分开发
游戏数据同步问题
网络延迟,那TCP为什么比UDP慢
做游戏的时候帧同步和状态同步怎么选择吧
一般现在的网络延迟100ms到200ms的样子,也就是说用户屏幕点击事件0.1s之后才会有响应,其实还是会被用户察觉,说下怎么优化?
那你觉得你玩吃鸡的时候数据传输到网络用的什么协议(UDP)
为什么用UDP(因为TCP会有三次握手、拥塞控制等一系列的措施,这样如果在网络情况不好情况下,那游戏会直接挂掉)
说说在弱网络或者丢包的情况下TCP怎么处理的(其实就是想问慢开始、拥塞避免、快恢复这几个过程的转换)
知道RTO、RTT吗
网络中7层和4层模型的区别
RST报文和哪个信号相关
TCP的nagle算法和延迟ack,还有CORK呢?他们有什么好处?一起用会有什么效果?你觉得可以有什么改进?
nagle算法:防止网络中存在太多小包而造成网络拥塞
延迟ack:减少ACK包的频繁发送
CORK:将多个包变成一个包发送,提高网络利用率,使载荷率更大
不可一起使用
停止等待协议的缺点?为什么?
信道利用率太低,每次都需要等上一次ACK包接收到了才能再次发送
当接受方的接受窗口为0时还能接受数据吗?为什么?还能接受什么数据?那怎么处理这些数据呢?
可以接受。
数据:零窗口探测报文;确认报文段;携带紧急数据的报文段
可能会被抛弃
当接受方的返回的接受窗口为0时,发送方会进行什么操作?
开启计时器,发送零窗口探测报文
1. TCP(UDP,IP)等首部的认识(http请求报文构成)
(1)IP首部
第一个4字节:
版本号:IPv4/IPv6;
首部长度,4位:用于标识首部的长度,单位为4字节,所以首部长度最大值为:(2^4 - 1) * 4 = 60字节,但一般只推荐使用20字节的固定长度。
总长度,16位;标识IP数据报的总长度
第二个四字节:
16位标识:数据报计数器,每产生一个数据报,计数器加1;
3位标志:MF=0—无分片,MF=1—有分片,DF—不分片
片偏移,13位;代表某个分片在原始数据中的相对位置。
第三个四字节:
生存时间TTL: 路由跳数;
8位协议:代表上层传输层协议的类型,1代表ICMP,2代表IGMP,6代表TCP,17代表UDP。
校验和,16位;用于验证数据完整性,计算方法为,首先将校验和位置零,然后将每16位二进制反码求和即为校验和,最后写入校验和位置。
(2)UDP首部
(3)TCP首部
第一个4字节:
源端口,16位;发送数据的源进程端口
目的端口,16位;接收数据的进程端口
第二,三个4字节:
序号,32位;代表当前TCP数据段第一个字节占整个字节流的相对位置;
确认号,32位;代表接收端希望接收的数据序号,为上次接收到数据报的序号+1,当ACK标志位为1时才生效。
第四个4字节:
数据偏移,4位;实际代表TCP首部长度,最大为60字节。
6个标志位,每个标志位1位;
SYN,为同步标志,用于数据同步;
ACK,为确认序号,ACK=1时确认号才有效;
FIN,为结束序号,用于发送端提出断开连接;
URG,为紧急序号,URG=1是紧急指针有效;
PSH,指示接收方立即将数据提交给应用层,而不是等待缓冲区满;
RST,重置连接。
窗口值,16位;标识接收方可接受的数据字节数。
第五个4字节:
校验和,16位;用于检验数据完整性。
紧急指针,16位;只有当URG标识位为1时,紧急指针才有效。紧急指针的值与序号的相加值为紧急数据的最后一个字节位置。用于发送紧急数据。
2. IP地址分类
3. 网络层分片的原因与具体实现
(1) 原因
MTU(最大传输单元):是数据链路层的限制1500B,所以IP要分片
MSS(最大分段大小):是TCP的限制,双方可以协商,往往是减去两个头部,40B。链路层是以太网的是话是1460,internet是512B
UDP不分段,靠IP分片
(2)具体实现
发送方会在IP层将要发送的数据分成多个数据包分批发送,而接收方则将数据按照顺序再从新组织起来,等接收到一个完整的数据报之后,然后再提交给上一层传输层。IP头部有3位标志字段,标志是否为分片包。第一位无用,第二位DF=0:允许分片,DF=1:不允许。第三位MF=0:最后一片,MF=1:后面还有分片。13位offset表示偏移,用于IP重组时数据排序。
4. 介绍一下 网络层 ping的过程,分别用到了哪些协议
UDP-ICMP(internet 控制报文协议)-ARP(地址解析的协议,mac地址)-OSPF(开放最短路径优先,内部网关协议)
封装UDP-IP包,然后查看子网掩码看是否在同网段,如果在,那么找ARP缓存表,找不到发送ARP请求,最后转换成数据帧,发送——接收后从IP包提取数据交给ICMP协议处理,发送ICMP应答
如果不在同网段则交给路由器处理,解析到对应的路由器mac,发送,路由器再解析到最终的mac发送
故障基本就是DNS配置不正确unkown host name,没连接DNS服务器,或者路由的问题,网卡问题,IP地址不存在
(1)在同一网段内
(2)不在同一网段内
在主机A上运行“Ping 192.168.1.4”后,开始跟上面一样,到了怎样得到MAC地址时,IP协议通过计算发现D机与自己不在同一网段内,就直接将交由路由处理,也就是将路由的MAC取过来,至于怎样得到路由的MAC,跟上面一样,先在ARP缓存表找,找不到就广播吧。路由得到这个数据帧后,再跟主机D进行联系,如果找不到,就向主机A返回一个超时的信息。
5. 一个ip配置多个域名,靠什么识别?
6. 子网划分
划分子网的方法是从网络的主机号借用若干位作为子网号,将收到的数据包的目的Ip地址与子网掩码进行与操作,便可以得到子网的网络地址。
7. 假如报文大小超过MTU怎么办,会发生什么事情
会发生报文的丢失
8. ARP协议
ARP的作用是:从网络层使用的IP地址,解析出在数据链路层使用的硬件地址
9. ARP的位置
10. ARP的作用
11. 对路由协议的了解与介绍。
内部网关协议IGP包括RIP,OSPF,和外部网关协议EGP和BGP.
12. 路由协议所使用的算法。
D-V距离矢量算法(RIP,IGRP,EIGRP,BGP),L-S链路状态算法(也称SPF最短路径树算法,如ospf,isis)
13. 交换机与路由器的区别
ARP攻击,ARP欺骗?
网桥?虚拟设备对?
IP层如何找MAC地址?如果对应IP不在局域网呢?
DHCP协议是什么?使用什么端口?他的优劣?
DHCP协议:动态主机配置协议
客户端端口:68;服务端端口:67
说说DHCP协议执行的过程?
DHCP discover广播-》
《-DHCP offer广播
DHCP request-》
《-DHCP ack
在0.5T和0.875T会尝试新的租用,服务器不同意则返回nack否则是ack;
如果发生IP冲突则返回DHCP decline。
路由表一般包含什么?
1)网络地址(2)网络掩码(3)网关【下一跳服务器】(4)跃点数【距离】
1. http协议与TCP联系
Http连接是一种短连接,是一种无状态的连接。所谓的无状态,是指浏览器每次向服务器发起请求的时候,不是通过一个连接,而是每次都建立一个新的连接。
2. http/1.0和http/1.1的区别
http协议入门
3. HTTP2.0 的特点
(1)HTTP/2采用二进制格式而非文本格式
(2)HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个HTTP连接就可以实现多个请求响应
(3)使用报头压缩,HTTP/2降低了开销
(4)HTTP/2让服务器可以将响应主动“推送”到客户端缓存中
4. http的请求方法有哪些?get和post的区别。
(1)8中请求方法(前四种常用)
方法 | 操作 |
---|---|
GET | 请求读取由URL所标志的信息 |
POST | 给服务器添加信息(如,注释) |
PUT | 在指明的URL下存储一个文档 |
DELETE | 删除指明的URL所标志的资源 |
OPTION | 请求一些选项的信息 |
HEAD | 请求读取由URL所标志的信息的首部 |
TRACE | 用来进行环回测试的请求报文 |
CONNET | 用于代理服务器 |
(2)get和post的区别(重点)
5. http的状态码
状态码 | 类别 | 原因短语 |
---|---|---|
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
6. http和https的区别,由http升级为https需要做哪些操作
(1)主要区别
(2)由http升级为https
HTTPS 同 HTTP 一样,首先建立起 TCP 连接,但是建立好之后并不是立即发出请求,索要具体的资源,而是先和对方商量加密的密码。商量的加密密码的过程就是建立 TSL 连接的过程。其实并没有建立真实的连接,只是在刚刚建立好的 TCP 连接上,包裹上一层加密协议而已。但是也被形象的称作连接建立。具体建立方式如下:客服端发给服务器一个HELLO包,里面有我支持的加密协议列表。服务器收到后发送也给客户端发送一个HELLO数据包,数据包内包涵服务器挑选的加密算法,还包含自己的数字证书信息。你拿到他的数字证书信息之后就需要去向 CA 校验证书,校验成功后也知道了对方的公钥,就该通知服务器,我们以后对称加密的密码是多少,当然,这个密码是要用公钥加密的。在这条消息发送之前,客户端会先发送一条消息,告诉服务器,我下一个消息将使用你刚刚挑选的加密协议进行加密了,下一个消息是加密后的哦,不要搞错。之后将对称加密的密文发给服务器。服务器接收到之后,会根据对称密钥生成一系列复杂的加密算法,在传输给客服端,客户端收到后会给服务器发送一个 Finished Message ,服务器收到消息后也回一个 Finished Message。这时,我们终于完成了加密的准备工作,一切加密方式和密钥都商量好了,终于可以传输数据了。至此,TSL 建立连接的过程结束。
8. http中浏览器一个URL的流程,这个过程中浏览器做了什么?
(1) 域名解析成IP地址;
DNS服务器是基于UDP的,因此会用到UDP协议。
(2) 与目的主机进行TCP连接(三次握手);
(3) 浏览器向服务器发送HTTP请求,请求数据包
与服务器建立了连接后,就可以向服务器发起请求了。发送HTTP请求的过程就是构建HTTP的get请求报文,并通过TCP协议发送到服务器指定端口(HTTP协议80/8080,HTTPS协议443)。HTTP请求是由三部分组成:请求行、请求报头和请求正文。
http生成一个get请求报文,将该报文传给TCP层处理。如果采用https还会先对http数据进行加密。TCP层如果有需要先将HTTP数据包分片,分片依据路径MTU和MSS。TCP的数据包然后会发送给IP层,用到IP协议。IP层通过路由选路,一跳一跳发送到目的地址。当然在一个网段内的寻址是通过以太网协议实现(也可以是其他物理层协议,比如PPP,SLIP),以太网协议需要直到目的IP地址的物理地址,有需要ARP协议。
(4) 服务器处理收到的请求
服务器端收到请求后,由web服务器(准确来说应该是HTTP服务器)处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,知道了要调度哪些资源文件,再通过相应的这些文件处理用户请求和参数,并调用数据库信息 ,最后将结果通过web服务器返回浏览器客户端。
(5) 返回相应结果至浏览器
HTTP响应报文也是由三部分组成:状态码、响应报头和响应报文。
(6) 与目的主机断开TCP连接(四次挥手);
(7) 浏览器对页面进行渲染呈现给用户
9. 单条记录高并发访问的优化
12. http报文首部格式
(1)请求报文
分为:请求行,首部行,实体主体
(2)响应报文
分为:状态行、响应报头和响应报文
状态行有:http版本,状态码,解释状态码的简单描述
Ex: HTTP /1.1 404 NOT Found
13. XML是什么结构?
树结构
14. TCP和UDP相关的协议与端口号
运输层协议 | 应用层协议 | 应用 | 端口号 |
---|---|---|---|
UDP | DNS(域名系统) | 名字转换 | 53 |
UDP | TFTP(简单文件传输协议) | 文件传输 | 69 |
UDP | RIP(路由信息协议) | 路由选择协议 | |
UDP | DHCP(动态主机配置协议) | IP地址配置 | 67 |
UDP | SNMP(简单网络管理协议) | 网络管理 | 161 |
UDP | NFS(网络文件系统) | 远程文件服务器 | |
UDP | IGMP(网际组管理协议) | 多播 | |
TCP | SMTP(简单邮件传输协议) | 电子邮件 | 25 |
TCP | TELNET(远程终端协议) | 远程终端接入 | 23 |
TCP | HTTP(超文本传送协议) | 万维网 | 80 |
TCP | HTTPs | 万维网 | 443 |
TCP | FTP(文件传送协议) | 文件传输 | 21 |
15. 一个机器能够使用的端口号上限是多少,为什么?可以改变吗?那如果想要用的端口超过这个限制怎么办?
TCP/IP用一个16位端口号来标志一个端口,端口号上限是65535。
16. URL包括哪三个部分
<协议>://<主机>:<端口>/<路径>
1. 对称密码和非对称密码体系
(1)对称加密是最快速、最简单的一种加密方式,加密与解密用的是同样的密钥。
优点:算法公开、计算量小、加密速度快、加密效率高。
缺点:交易双方都使用同样钥匙,安全性得不到保证。此外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。而与公开密钥加密算法比起来,对称加密算法能够提供加密和认证却缺乏了签名功能,使得使用范围有所缩小。
典型的例子:DES(三重DES)
(2)非对称加密为数据的加密与解密提供了一个非常安全的方法,它使用了一对密钥,公钥和私钥。私钥只能由一方安全保管,不能外泄,而公钥则可以发给任何请求它的人。非对称加密使用这对密钥中的一个进行加密,而解密则需要另一个密钥。
优点:安全性更高,公钥是公开的,秘钥是自己保存的,不需要将私钥给别人。
缺点:加密和解密花费时间长、速度慢,只适合对少量数据进行加密。
2. 数字证书的了解(高频)
CA给用户颁发一个数字证书,证书中包含用户的公钥(这个公钥可以是用户自己生成的提交给CA的也可以是CA生成发给用户的)及相关身份信息。
CA是Certificate Authority的缩写,也叫“证书授权中心”。数字证书是由权威的CA机构颁发的无法被伪造的证书,用于校验发送方实体身份的认证。解决如上问题,只需要发送方A找一家权威的CA机构申请颁发数字证书,证书内包含A的相关资料信息以及A的公钥,然后将正文A、数字证书以及A生成的数字签名发送给B,此时中间人M是无法篡改正文内容而转发给B的,因为M不可能拥有这家CA的私钥,无法随机制作数字证书。当然,如果M也申请了同一家CA的数字证书并替换发送修改后的正文、M的数字证书和M的数字签名,此时B接收到数据时,会校验数字证书M中的信息与当前通信方是否一致,发现数字证书中的个人信息为M并非A,说明证书存在替换风险,可以选择中断通信。
为什么CA制作的证书是无法被伪造的?其实CA制作的数字证书内还包含CA对证书的数字签名,接收方可以使用CA公开的公钥解密数字签名,并使用相同的摘要算法验证当前数字证书是否合法。制作证书需要使用对应CA机构的私钥,因此CA颁发的证书是无法被非法伪造的。
3. RSA加密算法,MD5原理(MD5不算加密算法)
计算步骤:
4. 服务器攻击(DDos攻击)
从互联网上的成百上千个网站集中攻击一个网站,称为分布式拒绝服务DDoS。
5. 客户端为什么信任第三方证书
签名合法
1. 网络应用程序设计模式
2. 在TCP连接中,服务端的socket要做哪些?
每个tcp连接的两端都会关联一个套接字和该套接字指向的文件描述符。
当服务端收到了ack消息后,就表示三次握手完成了,表示和客户端的这个tcp连接已经建立好了。连接建立好的一开始,这个tcp连接会放在listen()打开的established queue队列中等待accept()的消费。
这个时候的tcp连接在服务端所关联的套接字是listen套接字和它指向的文件描述符。
当established queue中的tcp连接被accept()消费后,这个tcp连接就会关联accept()所指定的套接字,并分配一个新的文件描述符。也就是说,经过accept()之后,这个连接和listen套接字已经没有任何关系了。连接还是那个连接,只不过服务端偷偷地换掉了这个tcp连接所关联的套接字和文件描述符,而客户端并不知道这一切。但这并不影响双方的通信,因为数据传输是基于连接而不是基于套接字的,只要能从文件描述符中将数据放入tcp连接这根"管道"里,数据就能到达另一端。
监听套接字是在服务进程读取配置文件时,从配置文件中解析出要监听的地址、端口,然后通过socket()函数创建的,然后再通过bind()函数将这个监听套接字绑定到对应的地址和端口上。随后,进程/线程就可以通过listen()函数来监听这个端口(严格地说是监控这个监听套接字)。
已连接套接字是在监听到TCP连接请求并三次握手后,通过accept()函数返回的套接字,后续进程/线程就可以通过这个已连接套接字和客户端进行TCP通信。
3. 如果 server 没有 accept,连接会怎样?
并不一定需要accept()才能进行tcp通信,因为在accept()之前连接就以建立好了,只不过它关联的是listen套接字对应的文件描述符,而这个套接字只识别三次握手和四次挥手涉及到的数据,而且这个套接字中的数据是由操作系统内核负责的。可以想像一下,只有listen()没有accept()时,客户端不断地发起connect(),服务端将一直将建立仅只连接而不做任何操作,直到listen的队列满了。
4. epoll和select/poll的区别
epoll是实现I/O多路复用的一种方法,有水平触发(level trigger,LT,默认)和边缘触发(edge trigger,ET)两种工作模式,区别在于两种模式的返回就绪状态的时间不同。水平触发和select/poll的方式一样
水平触发
读:缓冲内容不为空返回读就绪
写:缓冲区还不满返回写就绪
边缘触发
读:
缓冲区由不可读变为可读
新数据到达,缓冲区中待读数据变多时
写:
当缓冲区由不可写变为可写
当有旧数据被发送走,即缓冲区中的内容变少的时候
epoll之所以高效,是因为epoll将用户关心的文件描述符放到内核里的一个事件表中,而不是像select/poll每次调用都需要重复传入文件描述符集或事件集。比如当一个事件发生(比如说读事件),epoll无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入就绪队列的描述符集合就行了。
select的几大缺点:
(1) 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
(2) 同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
(3) select支持的文件描述符数量太小了,默认是1024
epoll和select和poll的调用接口上的不同,select和poll都只提供了一个函数——select或者poll函数。而epoll提供了三个函数,epoll_create,epoll_ctl和epoll_wait,epoll_create是创建一个epoll句柄;epoll_ctl是注册要监听的事件类型;epoll_wait则是等待事件的产生。
epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。
epoll的解决方案不像select或poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表)。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd
epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。
总结:
(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。
5. 建立TCP服务器的各个系统调用
建立TCP服务器连接的过程中主要通过以下系统调用序列来获取某些函数,这些系统调用主要包括:socket(),bind(),listen(),accept(),send()和recv()。
(1)套接字层接收进行的任何 TCP 系统调用。套接字层验证 TCP 应用程序传递的参数的正确性。这是一个独立于协议 的层,因为尚未将协议连接到调用中。
(2)套接字层下面是协议层,该层包含协议的实际实现(本例中为 TCP)。当套接字层对协议层进行调用时,将确保对两个层之间共享的数据结构具有独占访问权限。这样做是为了避免任何数据结构损坏。
(3)各种网络设备驱动程序在接口层运行,该层从物理链路接收数据,并向物理链路传输数据。
(4)每个套接字具有一个套接字队列,并且每个接口具有一个用于数据通信的接口队列。不过,对于整个协议层,只有一个称为 IP 输入队列的协议队列。接口层通过此 IP 输入队列将数据输入到协议层。协议层使用相应的接口队列将数据输出到接口。
socket所处层次:
1、创建一个socket套接字 2、绑定服务器的IP 和端口port 3、开启监听listen 将服务器的主动连接变成被动连接 4、等待客服端的请求连接 5、接收客服端的数据请求,向客服端发送数据
6. 继上一题,说明socket网络编程有哪些系统调用?其中close是一次就能直接关闭的吗,半关闭状态是怎么产生的
由于是双向的,两边都要发FIN,服务器关闭socket,用close会将该socket的计数-1,如果引用还是大于0,那么socket端口状态保持不变,如果为0,会将sender缓冲中的数发出去,然后发送FIN。可能在多进程中出现半关闭,所以应该使用
shutdown(sockfd, SHUT_RDWR); close(sockfd);
shutdown不考虑描述符的引用计数,直接关闭描述符,到LAST_ACK状态。也可选择中止一个方向的连接,只中止读或只中止写。
如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程都调用了close,套接字将被释放。
在多进程中如果一个进程调用了shutdown(sfd, SHUT_RDWR)后,其它的进程将无法进行通信。但,如果一个进程close(sfd)将不会影响到其它进程。
就是说可能会有多个进程共享使用一个socket。其它的系统调用有
客户端:socket,bind,connect,send,recv,close
服务器:socket,bind,listen,accept,recv,send,close
7. shutdown() 和 close() 有什么区别?如何优雅关闭 socket ?
通用的close()函数可以关闭一个文件描述符,当然也包括面向连接的网络套接字描述符。当调用close()时,将会尝试发送send buffer中的所有数据。但是close()函数只是将这个套接字引用计数减1,就像rm一样,删除一个文件时只是移除一个硬链接数,只有这个套接字的所有引用计数都被删除,套接字描述符才会真的被关闭,才会开始后续的四次挥手中。对于父子进程共享套接字的并发服务程序,调用close()关闭子进程的套接字并不会真的关闭套接字,因为父进程的套接字还处于打开状态,如果父进程一直不调用close()函数,那么这个套接字将一直处于打开状态,将一直进入不了四次挥手过程。
而shutdown()函数专门用于关闭网络套接字的连接,和close()对引用计数减一不同的是,它直接掐断套接字的所有连接,从而引发四次挥手的过程。可以指定3种关闭方式:
1.关闭写。此时将无法向send buffer中再写数据,send buffer中已有的数据会一直发送直到完毕。
2.关闭读。此时将无法从recv buffer中再读数据,recv buffer中已有的数据只能被丢弃。
3.关闭读和写。此时无法读、无法写,send buffer中已有的数据会发送直到完毕,但recv buffer中已有的数据将被丢弃。
无论是shutdown()还是close(),每次调用它们,在真正进入四次挥手的过程中,它们都会发送一个FIN。
8. 大端和小端的区别?网络字节序是哪一个?
大端:低地址——高位
小端:低地址——低位
网络字节序采用大端字节序
9. UDP bind 和 connect 有什么用?
10. write 和 sendto 有什么区别?(recv,write,send,read,recvfrom,sendto区别)
在无连接的数据报socket方式下,由于本地socket并没有与远端机器建立连接,所以在发送数据时应指明目的地址,sendto() 函数原型为:
int sendto(int sockfd, const void *msg,int len , unsigned int flags,
const struct sockaddr *to, int tolen);
该函数比 send() 函数多了两个参数,to表示目地机的IP地址和端口号信息,而tolen常常被赋值为sizeof (struct sockaddr)。sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
recvfrom() 函数原型为:
int recvfrom(int sockfd,void *buf,int len,unsigned int lags,
struct sockaddr *from,int *fromlen);
from是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号。fromlen常置为sizeof (struct sockaddr)。当recvfrom() 返回时,fromlen 包含实际存入from中的数据字节数。recvfrom() 函数返回接收到的字节数或当出现错误时返回-1,并置相应的errno。
11. 对端异常掉线,本端调用 write 函数向 socket 写入数据,会出现什么情况?
写操作返回异常,无法将数据写入到socket中
12. 用过正则表达式吗?写一个32位IP地址的正则
egrep "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" regex
13. 有没有抓过TCP包,描述一下
tcpdump是对网络上的数据包进行截获的包分析工具,它支持针对网络层、协议、主机、网络或端口的过滤,并提供and、or、not等逻辑语句来去掉无用的信息。
只能抓取流过本机的包
tcpdump -c 10 -nn -i eth0 tcp dst port 22 //这里 src是源 dst是目的的意思