网络编程

Golang相关 

(5条消息) Socket 中粘包问题浅析及其解决方案_嘿嘿-CSDN博客_socket粘包

断点续传和下载原理分析 - LOVE SHARE - 博客园 (cnblogs.com)

HTTP keep-alive和TCP keepalive的区别,你了解吗? - 知乎 (zhihu.com)

如何设计一个亿级消息量的IM系统 - InfoQ 写作平台

掘金 (juejin.cn)

HTTP 协议 · 笔试面试知识整理 (hit-alibaba.github.io)

Go语言基础之网络编程 | 李文周的博客 (liwenzhou.com)

Go 语言网络轮询器的实现原理 | Go 语言设计与实现 (draveness.me)

网络编程面试题(2021最新版) - 知乎 (zhihu.com)

2021最常见的linux网络编程面试题【好文收藏】 - 知乎 (zhihu.com)

TCP、UDP、Socket、HTTP网络编程面试题(总结最全面的面试题!) - 知乎 (zhihu.com)

 

互联网的核心是一系列协议,总称为”互联网协议”(Internet Protocol Suite),正是这一些协议规定了电脑如何连接和组网。

主要协议分为:
Socket
接口抽象层
TCP / UDP
面向连接(可靠) / 无连接(不可靠)
HTTP1.1 / HTTP2 / QUIC(HTTP3)
超文本传输协议

 应用程序通常通过“套接字”向网络发出请求或者应答网络请求。

一种通用的面向流的网络接口

主要操作:
建立、接受连接
读写、关闭、超时
获取地址、端口

TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议。

服务端流程:

  • 监听端口
  • 接收客户端请求建立连接
  • 创建 goroutine 处理连接

客户端流程:

  • 建立与服务端的连接
  • 进行数据收发
  • 关闭连接

 

 (5条消息) TCP的拥塞控制(详解)_努力进阶的小菜鸟-CSDN博客_tcp拥塞控制

系统调优,你所不知道的TIME_WAIT和CLOSE_WAIT (qq.com)

第二个问题,TIME_WAIT有什么用?

 

如果我们来做个类比的话,TIME_WAIT的出现,对应的是你的程序里的异常处理,它的出现,就是为了解决网络的丢包和网络不稳定所带来的其他问题:

CLOSE_WAIT才可怕,因为CLOSE_WAIT很多,表示说要么是你的应用程序写的有问题,没有合适的关闭socket;要么是说,你的服务器CPU处理不过来(CPU太忙)或者你的应用程序一直睡眠到其它地方(锁,或者文件I/O等等),你的应用程序获得不到合适的调度时间,造成你的程序没法真正的执行close操作。

第二,确保连接方能在时间范围内,关闭自己的连接。其实,也是因为丢包造成的,参见下图:

 

 

 

 

 

  • 主动关闭方关闭了连接,发送了FIN;

  • 被动关闭方回复ACK同时也执行关闭动作,发送FIN包;此时,被动关闭的一方进入LAST_ACK状态

  • 主动关闭的一方回去了ACK,主动关闭一方进入TIME_WAIT状态;

  • 但是最后的ACK丢失,被动关闭的一方还继续停留在LAST_ACK状态

  • 此时,如果没有TIME_WAIT的存在,或者说,停留在TIME_WAIT上的时间很短,则主动关闭的一方很快就进入了CLOSED状态,也即是说,如果此时新建一个连接,源随机端口如果被复用,在connect发送SYN包后,由于被动方仍认为这条连接【五元组】还在等待ACK,但是却收到了SYN,则被动方会回复RST

  • 造成主动创建连接的一方,由于收到了RST,则连接无法成功

TCP四次挥手也遵循相似的套路。

主动断开的一侧为A,被动断开的一侧为B。

第一个消息:A发FIN

第二个消息:B回复ACK

第三个消息:B发出FIN

此时此刻:B单方面认为自己与A达成了共识,即双方都同意关闭连接。

此时,B能释放这个TCP连接占用的内存资源吗?不能,B一定要确保A收到自己的ACK、FIN。

所以B需要静静地等待A的第四个消息的到来:

第四个消息:A发出ACK,用于确认收到B的FIN

当B接收到此消息,即认为双方达成了同步:双方都知道连接可以释放了,此时B可以安全地释放此TCP连接所占用的内存资源、端口号。

所以被动关闭的B无需任何wait time,直接释放资源。

但,A并不知道B是否接到自己的ACK,A是这么想的:

1)如果B没有收到自己的ACK,会超时重传FiN

那么A再次接到重传的FIN,会再次发送ACK

2)如果B收到自己的ACK,也不会再发任何消息,包括ACK

无论是1还是2,A都需要等待,要取这两种情况等待时间的最大值,以应对最坏的情况发生,这个最坏情况是:

去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)。

这恰恰就是2MSL( Maximum Segment Life)。

等待2MSL时间,A就可以放心地释放TCP占用的资源、端口号,此时可以使用该端口号连接任何服务器。

为何一定要等2MSL?
如果不等,释放的端口可能会重连刚断开的服务器端口,这样依然存活在网络里的老的TCP报文可能与新TCP连接报文冲突,造成数据冲突,为避免此种情况,需要耐心等待网络老的TCP连接的活跃报文全部死翘翘,2MSL时间可以满足这个需求(尽管非常保守)!

TCP keepalive指的是TCP保活计时器(keepalive timer)。设想有这样的情况:客户已主动与服务器建立了TCP连接。但后来客户端的主机突然出故障。显然,服务器以后就不能再收到客户发来的数据。因此,应当有措施使服务器不要再白白等待下去。这就是使用保活计时器。服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两小时。若两小时没有收到客户的数据,服务器就发送一个探测报文段,以后则每隔75秒发送一次。若一连发送10个探测报文段后仍无客户的响应,服务器就认为客户端出了故障,接着就关闭这个连接。

​ ——摘自谢希仁《计算机网络》

UDP 协议(User Datagram Protocol)中文名称是用户数据报协议,是 OSI(Open System Interconnection,开放式系统互联)参考模型中一种无连接的传输层协议。

一个简单的传输层协议
不需要建立连接
不可靠的、没有时序的通信
数据报是有长度(65535-20=65515)
支持多播和广播
低延迟,实时性比较好
应用于用于视频直播、游戏同步

(5条消息) http请求报文和响应报文_Lyn&Xx-CSDN博客_报文

HTTP(HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议,它详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。

请求报文:
Method: HEAD/GET/POST/PUT/DELETE
Accept:text/html、application/json
Content-Type:
application/json
application/x-www-form-urlencoded
请求正文
响应报文:

  • 状态行(200/400/500)
  • 响应头(Response Header)
  • 响应正文

 

HTTP 发展史:
1991 年发布初代 HTTP/0.9 版
1996 年发布 HTTP/1.0 版
1997 年是 HTTP/1.1 版,是到今天为止传输最广泛的版本
2015 年发布了 HTTP/2.0 版,优化了 HTTP/1.1 的性能和安全性
2018 年发布的 HTTP/3.0 版,使用 UDP 取代 TCP 协议
HTTP2:

  • 二进制分帧,按帧方式传输
  • 多路复用,代替原来的序列和阻塞机制
  • 头部压缩,通过 HPACK 压缩格式
  • 服务器推送,服务端可以主动推送资源

HTTP3:

  • 连接建立延时低,一次往返可建立HTTPS连接
  • 改进的拥塞控制,高效的重传确认机制
  • 切换网络保持连接,从4G切换到WIFI不用重建连接

 keep-alive机制:若开启后,在一次http请求中,服务器进行响应后,不再直接断开TCP连接,而是将TCP连接维持一段时间。在这段时间内,如果同一客户端再次向服务端发起http请求,便可以复用此TCP连接,向服务端发起请求,并重置timeout时间计数器,在接下来一段时间内还可以继续复用。这样无疑省略了反复创建和销毁TCP连接的损耗

 

Linux下主要的IO模型分为:

  • Blocking IO - 阻塞I O
  • Nonblocking IO - 非阻塞IO
  • IO multiplexing - IO 多路复用
  • Signal-driven IO - 信号驱动式IO(异步阻塞)
  • Asynchronous IO - 异步IO

同步:调用端会一直等待服务端响应,直到返回结果
异步:调用端发起调用之后不会立刻返回,不会等待服务端响应
阻塞:服务端返回结果之前,客户端线程会被挂起,此时线程不可被 CPU 调度,线程暂停运行
非阻塞:在服务端返回前,函数不会阻塞调用端线程,而会立刻返回

 

 

 

 

Go 语言在采用 I/O 多路复用 模型处理 I/O 操作,但是他没有选择最常见的系统调用 select。

虽然 select 也可以提供 I/O 多路复用的能力,但是使用它有比较多的限制

  • 监听能力有限 — 最多只能监听 1024 个文件描述符;
  • 内存拷贝开销大 — 需要维护一个较大的数据结构存储文件描述符,该结构需要拷贝到内核中;
  • 时间复杂度 𝑂(𝑛) — 返回准备就绪的事件个数后,需要遍历所有的文件描述符;

I/O多路复用:进程阻塞于 select,等待多个 IO 中的任一个变为可读,select调 用返回,通知相应 IO 可以读。 它可以支持单线程响应多个请求这种模式。

多路复用 select 

 epoll

中减少内存拷贝,mmap将用户空间的一块地址和内核空间的一块地址同时映射到相同的一块物理内存地址

epoll==>时间复杂度O(1)

  • 1、没有最大并发连接的限制,能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口);
  • 2、效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数;
  • 即Epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll的效率就会远远高于select和poll。
  • 3、 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销

网络协议

首先,你的计算机将向该Web服务器发送一条连接请求报文,并等待回答。 该Web服务器将最终能接收到连接请求报文,并返回一条连接响应报文。得知请求该 Web文档正常以后,计算机则在一条GET报文中发送要从这台Web服务器上取回的网页 名字。最后,Web服务器向计算机返回该Web网页(文件)。

面试官:讲讲DNS的原理? - 知乎 (zhihu.com)

 

posted on 2021-09-27 09:45  Ssumer  阅读(28)  评论(0编辑  收藏  举报

导航