计算机网络

计算机网络:

1、内核态用户态

1)为什么分这两个:1、为了安全。内核是进行硬件交互、资源管理的(不用程序员开发,简便了步骤),内存分为实地址模式和保护模式,在开机时候会把内存分为两部分一部分专门供内核进程使用一部分给用户进程使用,用户进程通过系统调用的方式调内核里的方法,这样用户进程就不能修改内核地址空间,这样防止了病毒改别人的进程。2、为了并发。如果用户进程不主动让出cpu那么别的进程就会饿死,怎么解决,通过晶振(物理硬件:直流电转化成时间段内规律的电流)规律的产生时钟中断,然后去查中断向量表找到回调函数cpu执行切换进程的操作。

2)进入内核态的方式:1、发生系统调用(软中断int 0x80)的时候会切换到内核进行调度。2、程序发生异常(除数为0,访问了非法的地址空间,缺页)。3、外围设备中断(晶振、当外设完成用户的请求时,会向CPU发送相应中断信号当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号)。

3)为什么切换会使系统变慢:1、保存用户程序得上下文,切内核态执行,然后恢复现场,2、每个进程都会有两个栈,一个内核态栈和一个用户态栈。当执行int中断执行时就会由用户态,栈转向内核栈。系统调用时需要进行栈的切换。3、而且内核代码对用户不信任,需要进行额外的检查。系统调用的返回过程有很多额外工作,比如检查是否需要调度等。

4)怎么解决频繁切换:1、无锁并发2、CAS 3、协程 4、零拷贝

5)文件描述符:非负整数,指向内核为每个进程维护的打开文件记录表,比如创建socket链接的时候先socket(),这时候底层其实是socket=3,这个3就是一个文件描述符,后面的传参都是用的这个文件描述符来传递这个对象。

2、BIONIOselect/pollepoll

1、BIO:同步阻塞IO,创建socket、bind、listen之后会循环accept(等待客户端链接)这时候会阻塞,建立链接后又resv(等待客户端传递信息)这时候又会阻塞,所以这时候为了不妨碍第二个客户端进来会启一个线程去处理cpu单位时间每个线程轮一下,总结:每次链接会建立一个线程去处理这样会频繁产生线程切换、系统调用浪费资源。(官方:用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。)

2、NIO:同步非阻塞IO,socket设置nonblock(内核提供的支持),一直在accept有则返回加入到客户端list,没有则返回0 -1,之后在循环客户端list看有没有resv有则返回没有返回0,这样只有一个线程就能支持了。但是一直发生系统调用浪费资源。(官方:用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。)

3、多路复用IO:

1)select:从用户轮询变成内核轮询,使用fd_set数组(最大1024),将fd数组拷贝到内核中,内核select阻塞轮询(>0成果,-1出错,0超时),找到后返回,用户处理,然后再次进入轮询,这次轮询会复制新的fd数组到用户,缺点:1、fdset数组不可重用,每次都拷贝fd从用户态到内核态,2、文件描述符最大1024个。

            扩展:

       1、int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);其中fd_set可读、可写和异常等事件,通过这三参数传入要监听的文件描述符,nfds最大描述符+1。

          2、fdset数组是long int类型大小16,因此能支持的最大fd数量便是8 x 8 x 16 = 1024个。值得注意的是,select函数返回时,内核会修改readfds、writefds、exceptfds中的值(就绪的位被置为1,其余全置为0),便于FD_ISSET来测试哪些描述符就绪。但那些我们加入的还没有就绪的文件描述符也被清0了,所以,每次重新调用select函数时,都得再次把所有描述符集内所关心的位均置为1。

          3、超时时间设置微妙单位:timeout 1、null:一直等直到有,2、大于0:至少等待一个或者时间到,3、0:检查后立即返回即轮询。

2)poll:与select传递数组不同,他传递的是pollfd结构体(fd+events请求的事件+revents返回的事件)他是链表,每次只改变结构体event字段标记(毫秒)使用poll无需重新重置pollfd类型的事件集参数,因为内核每次修改的是pollfd结构体的revents成员,而events成员保持不变。

他俩区别:1、select由于使用的是位运算,所以select需要分别设置read/write/error fds的掩码。而poll是通过设置数据结构中fd和event参数来实现read/write,2、select使用的是定长数组,而poll是通过用户自定义数组长度的形式,3、select的精度是微秒(timeval的分度),poll的精度是毫秒,4、select只支持最大fd < 1024,如果单个进程的文件句柄数超过1024,select就不能用了。poll在接口上无限制,

3)epoll:

          1、函数

                    1、定义三个方法处理select,新建epoll描述符==epoll_create()

                    2、epoll_ctrl(epoll描述符,添加或者删除所有待监控的连接、已注册的描述符在内核中会被维护在一棵红黑树上)

                    3、返回的活跃连接 ==epoll_wait( 通过回调函数内核会将 I/O 准备好的描述符加入到一个链表中管理,进程调用 epoll_wait() 便可以得到事件完成的描述符 )。

          2、优点:1、与select相比,epoll分清了频繁调用和不频繁调用的操作。epoll_ctrl不频繁调用的,而epoll_wait频繁调用。这时,epoll_wait却几乎没有入参,这比select的效率高出一大截,而且,它也不会随着并发连接的增加使得入参越发多起来,导致内核执行效率下降。epoll是通过内核与用户空间mmap同一块内存实现的。mmap将用户空间的一块地址和内核空间的一块地址同时映射到相同的一块物理内存地址(不管是用户空间还是内核空间都是虚拟地址,最终要通过地址映射映射到物理地址),使得这块物理内存对内核和对用户均可见,减少用户态和内核态之间的数据交换。内核可以直接看到epoll监听的句柄,效率高。2、红黑树存epoll所监听的套接字。时间复杂度O(logN)。3、红黑树事件都会与相应的设备(网卡)驱动程序建立回调关系,当相应的事件发生后,就会调用这个回调函数,该回调函数在内核中被称为:ep_poll_callback,这个回调函数其实就所把这个事件添加到rdllist这个双向链表中。一旦有事件发生,epoll就会将该事件添加到双向链表中。那么当我们调用epoll_wait时,epoll_wait只需要检查rdlist双向链表中是否有存在注册的事件,效率非常可观。这里也需要将发生了的事件复制到用户态内存中即可。

          3、epoll_wait的工作流程:

                    1、epoll_wait调用ep_poll,当rdlist为空(无就绪fd)时挂起当前进程,直到rdlist不空时进程才被唤醒。

                    2、文件fd状态改变(buffer由不可读变为可读或由不可写变为可写),导致相应fd上的回调函数ep_poll_callback()被调用。

                 3、ep_poll_callback将相应fd对应epitem加入rdlist,导致rdlist不空,进程被唤醒,epoll_wait得以继续执行。

                    4、ep_events_transfer函数将rdlist中的epitem拷贝到txlist中,并将rdlist清空。

                   5、ep_send_events函数(很关键),它扫描txlist中的每个epitem,调用其关联fd对用的poll方法。此时对poll的调用仅仅是取得fd上较新的events(防止之前events被更新),之后将取得的events和相应的fd发送到用户空间(封装在struct epoll_event,从epoll_wait返回)。     

但在进程调用epoll_wait()时,仍然可能被阻塞。能不能不用我老是去问你数据是否准备就绪,等我发出请求后,你数据准备好了通知我就行了,这就诞生了信号驱动IO模型。

 

4、零拷贝

1)、流程:1、read,切换内核+DMA拷贝到内核缓冲区。2、切换用户+cpu拷贝到用户缓冲区。3、write 切内核+拷贝到socket缓冲区。4、Socket 缓冲区网络协议引擎。5、write 方法返回,再次从内核态切换到用户态。(四次切换  4拷贝)

2)、mmap:mmap 通过内存映射,将文件映射到内核缓冲区,同时,用户空间可以共享内核空间的数据。这样,在进行网络传输时,就可以减少内核空间到用户空间的拷贝次数。(四次切换  3拷贝)

3)、sendfile:sendfile系统调用利用DMA引擎将文件内容拷贝到内核缓冲区去,然后将带有文件位置和长度信息的缓冲区描述符添加socket缓冲区去,这一步不会将内核中的数据拷贝到socket缓冲区中,DMA引擎会将内核缓冲区的数据拷贝到协议引擎中去,避免了最后一次拷贝。1、先是将内存中的数据DMA到内核缓冲区,2、使用scater gather,拷贝地址和长度到另一个socket缓冲区,3、DMA引擎gather搜集两个buffer中的数据到buffer再发送。

4)、mmap 和 sendFile 的区别。

          1、mmap 适合小数据量读写,sendFile 适合大文件传输。

          2、mmap 需要 4 次上下文切换,3 次数据拷贝;sendFile 需要 3 次上下文切换,最少 2 次数据拷贝。

          3、sendFile 可以利用 DMA 方式,减少 CPU 拷贝,mmap 则不能(必须从内核拷贝到 Socket 缓冲区)。

          4、在这个选择上:rocketMQ 在消费消息时,使用了 mmap。kafka 使用了 sendFile。

3、Linux 5种IO模型

1、阻塞IO

2、非阻塞IO

3、IO复用

4、信号驱动IO信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号),然后应用用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过SIGIO信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用recvfrom,去读取数据。在数据从内核复制到应用缓冲的时候,都是阻塞的。

5、异步IO:AIO实现了IO全流程的非阻塞,就是应用进程发出系统调用后,是立即返回的,但是立即返回的不是处理结果,而是表示提交成功类似的意思。等内核数据准备好,将数据拷贝到用户进程缓冲区,发送信号通知用户进程IO操作执行完毕。

只要有resv就是同步,buff直接用就是异步。

 

 

4、OSI网络模型

1、应用层:(http、DNS、SSH、SMTP、FTP)应用交互的协议,netstat -natp内核维护socket信息,程序读rec-q队列。

proto  rec-q  send-q  laddr  faddr  stat  pid/name

 tcp    6       0      192.。      listen  -          

2、表示层:编码、数据格式转换和加密解密。

3、会话层:组织和协调两个会话进程之间的通信,并对数据交换进行管理。

4、传输层:(TCP、UDP)主机之间通信。

5、网络层:(ipv4、ipv6、ARP、ICMP)使用ip协议为分组交换网络不同主机提供通信服务。IP协议

 

首部20字节。

标识 : 同一个 IP 数据报 的分片 , 使用相同的标识 ; IP 数据报大小超过 MTU 时 , 将数据报分片 , 分片完成的 IP 数据报分片 , 其标识都是相同的 ;

标志 : 由 3 33 位组成 , [ 48 , 50 ] [ 48 , 50 ][48,50] , 只有 2 22 位有意义 ;

最高位 : 是保留位 , 没有意义 ;

中间位 : DF 位 , DF = 1 时 , 禁止分片 ; DF = 0 时 , 允许分片 ;

最低位 : MF 位 , MF = 1 时 , 后面还有分片 ; MF = 0 时 , 最后一个分片 , 后面没有分片 ;

只有 DF = 0 时 , MF 才有意义 ;

片偏移 : 较长的分组的分片 , 中间的某个分片 , 在原来的 IP 分组中的相对位置 ; 单位是 8 88 字节 ; 也就是说除了最后一个分片 , 每个分片的长度是 8 88 字节的整数倍 ;

6、数据链路层:(以太网、LAN)arp请求mac地址。

7、物理层:(光纤、电缆)。

5、发http流程

发送  ->  sip+Rmac  ->  sip+Smac  ->  sip+S-mac   ->  server

          c                R路由器       ISP运营商       S

1、应用层:域名解析(浏览器域名缓存+本地路由缓存)2、传输层:封装udp广播,3、网络层:包装ip请求头,3、数据链路层:加mac地址,通过arp协议广播请求mac地址。4、物理介质传到路由器(3层网络、数据链路、物理),解析后看要传的下一个ip mac是多少,5、传到运营商路由器返回拿到ip,6、原路返回到客户端解析回应用层,7、发http请求,8、传输层:包装tcp请求,9、包装ip请求头,10、数据链路层:加mac地址,11、走路由到供应商,12到server

浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;

解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;

浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;

服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;

释放 TCP连接;

浏览器将该 html 文本并显示内容;

6、http协议

1、是什么:基于TCP/IP的请求应答模式的无链接的超文本传输协议,用来传数据,默认80。

2、http特点:1)http无连接:限制每次连接只处理一个请求,服务端完成客户端的请求后,即断开连接。(传输速度快,减少不必要的连接,但也意味着每一次访问都要建立一次连接,效率降低);(2)http无状态:对于事务处理没有记忆能力。每一次请求都是独立的,不记录客户端任何行为;(3)客户端/服务端模型:客户端支持web浏览器或其他任何客户端;(4)简单快速;(5)灵活:可以传输任何类型的数据。

3、cookies机制和session机制的区别是什么:(1)cookies数据保存在客户端,session数据保存在服务端;(2)cookies可以减轻服务器压力,但是不安全,容易进行cookies欺骗;(3)session安全一点,但是占用服务器资源。

4、GET、POST区别:1、get是获取资源url后,post是提交信息http body中,2、get大小有限制1024k,post没有,3、GET产生一个TCP数据包,POST产生两个TCP数据包。严格的说:对于GET方式的请求,游览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST请求。游览器先发送header,服务器响应100continue,游览器再发送data,服务器响应200 ok(返回数据)。4、get被浏览器缓存,post没有。

5、Http协议有什么组成:请求报文包含三部分:请求行:包含请求方法、URI、HTTP版本信息;请求首部字段;请求内容实体。

响应报文包含三部分:状态行:包含HTTP版本、状态码、状态码的原因短语;响应首部字段;响应内容实体。

6、Http协议中有那些请求方式:

GET:用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器。

POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST方式。

PUT: 传输文件,报文主体中包含文件内容,保存到对应URI位置。

HEAD: 获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效。

DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件。

OPTIONS:查询相应URI支持的HTTP方法。

7、状态码:

100(接受的请求正在处理)100continue客户端应该继续请求。

200(成功状态码)200 ok,201 create,202 accept

300(重定向)301 (表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。)302 found(表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。)

400(客户端错误)400 bad req 403 forbidden 404

500 (服务器错误)502 代理错误 503 网络服务正忙,请稍后重试

8、http常见字段:1、Host指定域名,2、Content-Length长度,3、Connection要求持久连接=Keep-Alive http1.1,4、Content-Type 指定格式,5、

9、优点:1、简单(header+body+key value方式),2、易于拓展(https加了tls/ssl),3、跨平台应用广泛

   缺点:1、无状态(节省资源但是连接费时-session)2、不安全(明文传输)

10、HTTP/1.1、 HTTP/1.0 、HTTP/2、HTTP/3:

http/1.1

          1、使用 TCP 长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。

          2、支持 管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。但是有队头阻塞问题。

          3、出现的问题:

                    1、请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body 的部分;

                    2、发送冗长的首部。每次互相发送相同的首部造成的浪费较多;

                    3、服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞;

                    4、没有请求优先级控制;

                    5、请求只能从客户端开始,服务器只能被动响应。

http/2

          1、头部压缩:如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的分(HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。)

          2、二进制格式:头和body采用二进制发送

          3、数据流:每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数,客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求。

          4、并发:解决队头阻塞

          5、服务器推送:在浏览器刚请求 HTML 的时候,就提前把可能会用到的 JS、CSS 文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫 Cache Push)。

          6、支持断点续传,请求头设置。

          7、出现问题:1、复用tcp连接一旦发生丢包,就会阻塞住所有的 HTTP 请求进行tcp重传。

http/3

          1、TCP 协议改成了 UDP,基于udp的QUIC 协议可以实现类似 TCP 的可靠性传输。QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响。HTTPS 要建立一个连接,要花费 6 次交互,先是建立三次握手,然后是 TLS/1.3 的三次握手。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数。QUIC 是一个在 UDP 之上的伪 TCP + TLS + HTTP/2 的多路复用的协议。(1、tcp会连接迁移,每次连接都是新端口,QUIC 不以四元组作为标识,而是用64位随机数,这样ip端口换了也没事,2、但它不但具有TCP的可靠性、拥塞控制、流量控制等,且在TCP协议的基础上做了一些改进,比如避免了队首阻塞;另外,QUIC协议具有TLS的安全传输特性,实现了TLS的保密功能,同时又使用更少的RTT建立安全的会话。)

7、https

1、与http区别:

          1、安全(窃听、篡改、冒充)。加入了 SSL/TLS 安全协议,使得报文能够加密传输。

          2、握手次数。HTTP3次握手, HTTPS 3次后还要SSL/TSL握手。

          3、端口不一样。80、443。

        4、HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

2、保证安全方式:

          1、混合加密(窃听):RSA非对称加密(基于大数运算,比如大素数或者椭圆曲线,是复杂的数学难题,比较慢,体积大),AES对称加密(位运算)

          2、摘要算法生成指纹(篡改):hash算法MD5、SHA1、SHA256,发送前用摘要算法算出明文的指纹,发送时指纹+明文一起加密成,接受后用相同的摘要算法算出发送过来的明文,比较指纹。

          3、数字证书(冒充)将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。

生成:服务器保存私钥,公钥给CA,CA验证真实性,证书颁发包含公钥、公司信息、ca信息、过期时间同时生成签名。

证书是一层层套起来的,根证书在配置安装时存起来,

验证:根据hash算法验证证书签名,

3、建立连接过程:

          1、三次握手

          2、客户端发ClientHello(客户端支持的SSL/TLS版本,随机数,客户端支持的加密算法),服务器回ack

          3、服务器发SeverHello(确认SSL/TSL版本,随机数,加密算法)

          4、服务器发证书

          5、服务器发SeverDone,客户端回ack

          6、客户端验证证书,取公钥,加密发送(被公钥加密的随机数,加密算法改变通知,握手通知结束)

          7、服务端回应(加密算法改变通知,握手结束通知)

8、TCP

1、结构,(服务器端 MSS 为 1460,而客户端只有 1260)

 

          1)序号seq:解决乱序,随机生成,每次加数据字节大小

          2)确认号ack:下次期望收到的数据的序号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。

数据偏移:首部长度。

          3)控制位:

                    1、URG:紧急指针,发送缓冲区最后设置OOB标记,紧急指针指向OOB下一个字节,OOB前一个字节作为紧急数据发送,流量控制会控制住,发送端发送紧急数据后,接收端通过内核发送SIGURG信号或者select调用通知接收端进程发送端进入紧急模式这一信息.并使其进入特殊的接收模式接收带外数据和普通数据.)

                    2、ACK:确认应答

                    3、PSH:该报文希望,到达对端时,将这个报文及缓存区之间缓存尚未交付的数据一并交付给进程。push的数据是本报文数据+缓存区数据,PSH的方向--->单方向(接收PSH报文的一端)

                    4、RST:异常,表示 TCP 连接中出现异常必须强制断开连接。

                    5、SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。

                    6、FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。

          4)窗口大小:告诉发送端对它所发送的数据能供给多大的缓冲区。

          5)校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。

          6)紧急指针:一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。紧急指针是发送端向接收端发送紧急数据的方法。

 

2、特点:

面向连接的(一定是「一对一」才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;)、可靠的(无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端;)、基于字节流(消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节,那么也不能扔给应用层去处理,同时对「重复」的报文会自动丢弃。)的传输层通信协议。

3、如何唯一确定一个 TCP 连接呢:四元组

源地址和目的地址的字段(32位)是在 IP 头部中,作用是通过 IP 协议发送报文给对方主机。

源端口和目的端口的字段(16位)是在 TCP 头部中,作用是告诉 TCP 协议应该把报文发给哪个进程。

4、有一个 IP 的服务器监听了一个端口,它的 TCP 的最大连接数是多少?

最大:客户端Ip x客户端port = 2^32 * 2^16

有限制:1、文件描述符限制too many open files(系统级、用户级、进程级最大打开限制),2、内存OOM

5、TCP UDP区别

          1、连接:tcp面向连接,udp不需要先建立连接

          2、服务对象:tcp1对1,udp 1对1 多对1 多对多

          3、可靠性

          4、拥塞控制、流量控制,网络很堵不影响udp传输

          5、首部开销,udp8字节,tcp最少20字节

          6、传输方式:tcp流式没有边界,udp一个包一个包发有边界。

          7、分片不同:TCP 的数据大小如果大于 MSS 大小,则会在传输层进行分片收到后,也同样在传输层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。UDP 的数据大小如果大于 MTU 大小,则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完数据,接着再传给传输层。

6、tcp udp应用场景

          tcp保证可靠性用于ftp http,udp用于广播通信 dns 视频

7、tcp数据长度=ip总长-ip首部长度-tcp首部长度

8、三次握手:第三次握手是可以携带数据的,前两次握手是不可以携带数据的。

          1、为什么三次:1)第三次防止已经失效的连接重新传回服务器(网络拥堵新syn比久的先到,客户端收到ack后会回RST断开)。2)同步双方序号(去重、排序、重发的作用)3)避免资源浪费4)syn攻击

9、为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢?

          1、为了防止历史报文被下一个相同四元组的连接接收(服务器重启重新建立连接,老的请求过来了并且在滑动窗户内)

          2、为了安全性,防止黑客伪造的相同序列号的 TCP 报文被对方接收;

10、初始序列号 ISN 是如何随机产生的?

随机数是会基于时钟计时器递增的,ISN = M(4微妙+1) + F(四元组hash)

11、既然 IP 层会分片,为什么 TCP 层还需要 MSS 呢:因为ip分片传输如果一个 IP 分片丢失,整个 IP 报文的所有分片都得重传。而TCP只需要重传以 MSS 为单位的数据。(MTU 是链路层可封装数据的上限,以太网1500 字节 )

12、第一次握手丢失了,会发生什么:又内核控制重传次数1 2 4 8 16秒后进行5次重传,没有就断开。

13、syn攻击:syn队列占满

正常流程(a当服务端接收到客户端的 SYN 报文时,会将其加入到内核的「 SYN 队列」;b接着发送 SYN + ACK 给客户端,等待客户端回应 ACK 报文;c服务端接收到 ACK 报文后,从「 SYN 队列」移除放入到「 Accept 队列」;d应用通过调用 accpet() socket 接口,从「 Accept 队列」取出连接。)

          1、限制ip

          2、net.ipv4.tcp_syncookies = 1设置cookies(a当 「 SYN 队列」满之后,后续服务器收到 SYN 包,不进入「 SYN 队列」;b计算出一个 cookie 值,再以 SYN + ACK 中的「序列号」返回客户端,c务端接收到客户端的应答报文时,服务器会检查这个 ACK 包的合法性。如果合法,直接放入到「 Accept 队列」。d最后应用通过调用 accpet() socket 接口,从「 Accept 队列」取出的连接。)

          3、设置直接返回RST   net.ipv4.tcp_abort_on_overflow

14、客户端中途宕机

15、四次挥手:状态客户端(fin_wait_1,fin_wait_2,time_wait)服务端(close_wait, last_ack)

16、为什么 TIME_WAIT 等待的时间是 2MSL,linux默认msl=30秒:(TTL:ip最大路由数,一般64跳)1、保证被动关闭方能正确关闭,至少允许报文丢失一次。2、防止断开立即重连时四元组和序号匹配上。

17、如何优化 TIME_WAIT:

          1、复用处于 TIME_WAIT 的 socket 为新连接所用(只能用客户端,且开启TCP 时间戳的支持net.ipv4.tcp_tw_reuse 和 tcp_timestamps)。

          2、当系统中处于 TIME_WAIT 的连接一旦超过这个值时,系统就会将后面的 TIME_WAIT 连接状态重置(net.ipv4.tcp_max_tw_buckets)

          3、配置close时发送RST,配置SO_LINGER

18、如果已经建立了连接,但是客户端突然出现故障了怎么办:TCP 有一个机制是保活机制。定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。(启动保活时间2小时+每次检测间隔75秒+检测几次9)=2小时11分15秒。

          1、对面是正常的,重置时间,2、对面重启了,则返回RST,3、对面没响应,重试几次后会关闭。

19、TCP怎么保证可靠:

          1、有三次握手,而断开则是四次挥手。确保连接和断开的可靠性。

          2、切分成块运输。

          3、超时重传:RTO=略大于RTT(请求来回时间)发送完设置一个超时时间且超时时间间隔会加倍,缺点太慢了

          4、接收方对包排序后返回应用层

          5、校验和(首部+数据)

          6、重复数据丢弃

          7、流量控制:滑动窗口

          8、拥塞控制:慢开始、拥塞避免、快重传、快恢复

20、沾包

          1、出现的原因:

                    1、滑动窗口

粘包:假设发送方的每256 bytes表示一个完整的报文,接收方由于数据处理不及时,这256个字节的数据都会被缓存到接收缓存区中。如果接收方的接收缓存区中缓存了多个报文,那么对于接收方而言,这就是粘包。

拆包:考虑另外一种情况,假设接收方的窗口只剩了128,意味着发送方最多还可以发送128字节,而由于发送方的数据大小是256字节,因此只能发送前128字节,等到接收方ack后,才能发送剩余字节。这就造成了拆包。

                    2、MTU/MSS限制

                   3、Nagle算法(上一包分组得到确认,才会发送下一分组,2收集多个小组,在一个确认到来时一起发送)

(2)接收方问题

TCP接收方接收到分组的时候,并不会立刻提交到应用层处理,收到的数据放在接收缓存里面,然后应用程序会主动从接受缓存里读取接收的分组,这样以来,如果TCP接收分组的速度大于应用读取分组的速度,多个包的数据会存至缓存区里面,应用读取数据就可能会产生黏包问题。

2、解决:

1、长度编码:发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。

2、特殊字符分隔符协议:可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开。

3、定长协议:发送端将每个数据包封装为固定长度(不够的可以通过补0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。

3、udp为什么不会

TCP协议是面向流的协议,UDP是面向消息的协议

UDP每一段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据

UDP具有保护消息边界,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样对于接收端来说就容易进行区分处理了。传输协议把数据当作一条独立的消息在网上传输,接收端只能接收独立的消息。接收端一次只能接收发送端发出的一个数据包,如果一次接受数据的大小小于发送端一次发送的数据大小,就会丢失一部分数据,即使丢失,接受端也不会分两次去接收

21、UDP 和 TCP 有什么区别呢?分别的应用场景是?

UDP 不提供复杂的控制机制,利用 IP 提供面向「无连接」的通信服务。

UDP 协议真的非常简,头部只有 8 个字节( 64 位),UDP 的头部格式如下:

9、UDP

 

目标和源端口:主要是告诉 UDP 协议应该把报文发给哪个进程。

包长度:该字段保存了 UDP 首部的长度跟数据的长度之和。

校验和:校验和是为了提供可靠的 UDP 首部和数据而设计,防止收到在网络传输中受损的 UDP包。

1、带外数据:

传输层协议使用带外数据(out-of-band,OOB)来发送一些重要的数据,如果通信一方有重要的数据需要通知对方时,协议能够将这些数据快速地发送到对方。为了发送这些数据,协议一般不使用与普通数据相同的通道,而是使用另外的通道。linux系统的套接字机制支持低层协议发送和接受带外数据。但是TCP协议没有真正意义上的带外数据。为了发送重要协议,TCP提供了一种称为紧急模式(urgent mode)的机制。TCP协议在数据段中设置URG位,表示进入紧急模式。接收方可以对紧急模式采取特殊的处理。很容易看出来,这种方式数据不容易被阻塞,并且可以通过在我们的服务器端程序里面捕捉SIGURG信号来及时接受数据。这正是我们所要求的效果。

由于TCP协议每次只能发送和接受带外数据一个字节,所以,我们可以通过设置一个数组,利用发送数组下标的办法让服务器程序能够知道自己要监听的端口以及要连接的服务器IP/port。由于限定在1个字节,所以我们最多只能控制255个port的连接,255个内网机器(不过同一子网的机器不会超过255J),同样也只能控制255个监听端口,不过这些已经足够了。

一、Cache 和 Buffer

1、Cache 是为了弥补高速设备 和 低速设备的鸿沟而引入的中间层,最终起到加快访问速度的作用。

2、Buffer 的主要目的是进行流量整形,把突发的大数量较小规模的I/O 整理成平稳的小数量较大的规则的I/O,以减少响应次数。(如网上下载电影,不能下一点点就写一下硬盘,而是积攒一定量的数据以后一整块一起写,不然会影响硬盘寿命)。

3、Buffer(缓冲区) 是系统两端处理速度平衡(从长时间尺度上看)时使用的。它的引入是为了减小短期内突发I/O 的影响,起到流量整形的作用。比如生产者–消费者问题,它们产生和消耗资源的速度大体接近,加一个buffer 可以抵消掉资源刚产生/消耗时的突然变化。

4、Cache被用作CPU针对内存的缓存利用程序的空间局部性和时间局部性原理,达到较高的命中率,从而避免CPU每次都必须要与相对慢速的内存交互数据来提高数据的访问速率。每当Buffer 满或者主动flush buffer 的时候触发一次读取,对于小数据,这样就可以减少读取次数,对于大数据,这就可以控制单次读取的数据量。

5、Cache(缓存) 则是系统两端处理速度不匹配时的一种折中策略,目的在于提高性能。因为CPU 和memory 之间的速度差异越来越大,所以人们充分利用数据的局部性特征,通过使用存储系统分级的策略来减小这种差异带来的影响。

如果不比缓冲中读取,也可以直接读取实际数据,只不过实际数据读取时会慢一些。当这个数据在缓存中,读取速度将会变快。

当一个缓存中的数据被多次读取,实际上就减少了该数据从慢速设备中读取的量,这就存在某种算法去选择(什么数据需要保存在Cache中),因为尽可能多的让 Cache 命中就能提高性能。先进入Cache 的数据不一定先被读取,甚至说进入cache 的数据有可能永远不被读取就被清除了,因此 read cache 呈现出非常明显的随机访问特性。

假定以后存储器访问变得跟CPU 做计算一样快,cache 就可以消失,但是buffer 依然存在。比如,从网络上下载东西,瞬时速率可能会有较大变化,但从长期来看却是稳定的,这样能通过引入一个buffer 使得OS 接收数据的速率列稳定,进一步减少对磁盘的伤害。

6、TLB(Translation Lookaside Buffer)后备缓冲器,其实它是一个Cache。

二、Write Cache 和 Write Buffer

Write Buffer

对于小数据的写入,它需要填满write buffer 再进行一次写入,对于大数据,大数据会被分割为 buffer 尺寸的大小分批写入。

因此 write buffer 的用处在于使得每次写入的数据量相对固定。

如果一次写入 4k 对某个设备来说效率最高,那么 buffer 定为 4k, 小数据积攒 4k 写一次,大数据分割到每个碎片 4k 多次写入,这样就是 writer buffer 的用处。

Write Cache

对于Write Cache ,我们要设法减少写入次数,也就是说,如果某些数据需要产生多次写入,那么使用cache 就可以只将最终据写入,导致最终写入数据减少。

3、进程间通信方式IPC

1、管道:mkfifo,有名管道,无名管道(父子进程)在内存中,半双工

2、消息队列:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

3、共享存储:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

4、信号量:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制p-1 v+1。

5、套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

6、信号 ( sinal ) : 注册信号,触发信号,比如ctl c,kill。

4、线程之间通信:加锁,chnnel,sync.Cond

RPC:

1、定义:远程过程调用,屏蔽远程调用网络相关的细节,使得远程调用和本地调用使用一致,让开发的效率更高,一种架构,主要目标就是让远程服务调用更简单、透明,调用远程就像调用本地一样。主要解决了分布式系统中,服务与服务之间的调用问题。

2、RPC 架构主要包括三部分:

服务注册中心(Registry),负责将本地服务发布成远程服务,管理远程服务,提供给服务消费者使用。

服务提供者(Server),提供服务接口定义与服务实现类。

服务消费者(Client),通过远程代理对象调用远程服务。

服务提供者启动后主动向服务注册中心(Registry)注册机器IP、端口以及提供的服务列表;

服务消费者启动时向服务注册中心(Registry)获取服务提供方地址列表。

服务注册中心(Registry)可实现负载均衡和故障切换。

3、RPC步骤:

1、客户端(client)以本地调用方式调用服务;

2、客户端存根(client stub)接收到调用后,负责将方法、参数等组装成能够进行网络传输的消息体(将消息体对象序列化为二进制);

3、客户端通过 sockets 将消息发送到服务端;

4、服务端存根(server stub)收到消息后进行解码(将消息对象反序列化);

5、服务端存根(server stub)根据解码结果调用本地的服务;

6、本地服务执行并将结果返回给服务端存根(server stub);

7、服务端存根(server stub)将返回结果打包成消息(将结果消息对象序列化);

8、服务端(server)通过 sockets 将消息发送到客户端;

9、客户端存根(client stub)接收到结果消息,并进行解码(将结果消息发序列化);

10、客户端(client)得到最终结果。

RPC是把2、3、4、7、8、9 这些步骤都封装起来。

4、http对比rpc

1、传输协议

RPC,可以基于TCP协议,也可以基于HTTP协议

HTTP,基于HTTP协议

2、传输效率

RPC,使用自定义的TCP协议,可以让请求报文体积更小,或者使用HTTP2协议,也可以很好的减少报文的体积,提高传输效率

HTTP,如果是基于HTTP1.1的协议,请求中会包含很多无用的内容,如果是基于HTTP2.0,那么简单的封装以下是可以作为一个RPC来使用的,这时标准RPC框架更多的是服务治理

4、性能消耗,主要在于序列化和反序列化的耗时

RPC,可以基于thrift实现高效的二进制传输

HTTP,大部分是通过json来实现的,字节大小和序列化耗时都比thrift要更消耗性能

5、负载均衡

RPC,基本都自带了负载均衡策略

HTTP,需要配置Nginx,HAProxy来实现

6、服务治理(下游服务新增,重启,下线时如何不影响上游调用者)

RPC,能做到自动通知,不影响上游

HTTP,需要事先通知,修改Nginx/HAProxy配置

5、什么时候使用

RPC主要用于公司内部的服务调用,性能消耗低,传输效率高,服务治理方便。

HTTP主要用于对外的异构环境,浏览器接口调用,APP接口调用,第三方接口调用等。

6、pc是一种协议,grpc是基于rpc协议实现的一种框架。

协议约定。gRPC 的协议是 Protocol Buffers,是一种压缩率极高的序列化协议,Google 在 2008 年开源了 Protocol Buffers,支持多种编程语言,所以 gRPC 支持客户端与服务端可以用不同语言实现。

②传输协议。gRPC 的数据传输用的是 Netty Channel, Netty 是一个高效的基于异步 IO 的网络传输架构。Netty Channel 中,每个 gRPC 请求封装成 HTTP 2.0 的 Stream。

③服务发现。gRPC 本身没有提供服务发现的机制,需要通过其他组件

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值