• 三次握手
  • 四次挥手
  • 为啥time_wait需要等待2MSL?
  • 为啥会出现大量的close_wait?
  • 什么时候会出现FIN-WAIT?
  • TCP为啥需要流量控制?
  • 如何调整网络负载?
  • tcp为啥需要拥塞控制?
  • 慢开始和拥塞避免?
  • 快速重传和快速恢复?
  • 为什么出现粘包/拆包?

 

osi七层网络协议

 经典协议与数据包

 

 

 

 

 

 

 

 

 

 

 

 tcp三次握手

 

 tcp四次挥手

 

 

 

 

为啥time_wait需要等待2MSL?

1,MSL:Maximum Segment Lifetime,30秒-1分钟

2,保证TCP协议的全双工连接能够可靠关闭

3,保证这次连接的重复数据段从网络中消失

 

为啥会出现大量的close_wait?

1,首先close_wait一般书现在被动方关闭

2,并发请求太多导致

3,被动关闭方未及时释放端口资源导致

 

 

 CLOSE_WAIT产生原因
  close_wait是被动关闭连接是形成的,根据TCP状态机,服务器端收到客户端发送的FIN,TCP协议栈会自动发送ACK,链接进入close_wait状态。但如果服务器端不执行socket的close()操作,状态就不能由close_wait迁移到last_ack,则系统中会存在很多close_wait状态的连接;

说白的就是并发可能有点大,io不能及时切换过去,I/O线程被意外阻塞,I/O操作处理不及时,链路不能被及时释放

 

 tcp为啥需要流量控制

 

 

如何调整网络负载,tcp为啥需要拥塞控制?

 

 

  • 慢开始和拥塞避免

  • 快速重传和快速恢复

tcp拥塞控制  慢开始和拥塞避免

 

 所谓慢开始,tcp刚开始一点点传递试探一下网络的承受能力,以免扰乱网络通道的秩序

tcp拥塞控制  慢开始和拥塞避免

 

 上图中,图标3处遇到网络拥塞,就把拥塞的窗口直接降为1了,然后重新开始慢开始,一点点递增

为了优化慢开始所以对算法进行了优化:快重传和快恢复

 

tcp拥塞控制 快重传和快恢复

 

 

快速重传;当收到3个重复ACK 执行快重传:

会把当前拥塞窗口降为原来的一般。然后把拥塞避免的预值降为原来的一半,进入一个快速恢复的阶段

快速恢复:因为受到3次重复ack,丢包,只要是在这个阶段丢的包,会重复发送一遍,直到把所有丢失的包重新发送完毕后就会退出快速恢复阶段,

然后进入拥塞避免阶段

 

为什么出现?

tcp粘包和拆包

 

上图:

发送方由应用程序发送应用的报文,根据应用数据报文大小的不同,它会占用2个或者1个,应用的数据实际会发送到tcp的缓冲区里面(发送缓冲区)。真正发送是由linux内核走tcp连接发送;

tcp根据缓冲区大小来决定是否要粘包,粘包:多次请求合并到一个tcp报文中,拆包:一次请求拆到多个tcp报文里面,至于数据如何被包装都是由tcp底层去完成的。

因为我运用的其实是应用层,不需要关心它的细节,数据会流入接收方的接收缓冲区,接收方通过socket的reverve方法去获取到数据。

我们是在应用层通过socket 直接从bufer缓冲区拿取数据

 

 

如何获取完整应用的数据报文?

 

 

 如何获取完整的数据报文?

 

 

 实例代码:

 

 

 

golang创建udp服务和客户端

 

 

 

 

 

 

golang创建tcp服务器和客户端

 

 

 

 

 

 

客户端:defer conn.Close()  //思考题:这里不填写会有啥问题?(连接一直在建立状态,除非tcp连接探测后才会关闭)

 

 

服务端:defer conn.Close()  //思考题:这里不填写会有啥问题?
客户端发起了关闭,服务端没有关闭,此时按照四次挥手图分析:
客户端是主动关闭方,客户端此时处于FIN-WAIT-2;
服务端属于被动关闭方,服务端处于CLOSE-WAIT状态;

 

 

 

服务端:

  • 创建路由器;
  • 设置路由规则;
  • 创建服务器;
  • 监听端口并提供服务;

 

客户端:

  • 创建连接池:
  • 创建客户端;
  • 请求数据;
  • 读取内容;

 

 

 

golang http服务器源码分析:

  在分析httpserver源码之前,请看看此文章 ,了解下type func的用法,函数式一等公民概念,不然下面代码可能难以理解。

 从最简单的例子开始:

 

 

来看看HandleFunc是啥?

 

HandlerFunc(handler)

 此处就是用到了type关键字  把一个函数转成HandlerFunc 类型,并且实现了ServeHTTP方法

 

 ServeHTTP方法又实现了Handler接口

 

 

通过回调思路最终执行了sayBye()

 

 

 

 mu:一把锁

m:存放着路由和回调函数

 

h 注册的函数

pattern 注册的路由

 

注册路由

 

 

开启服务:

 

 

 

 

 

 

 处理链接:

 

func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)

 

 httpClient源码简单解析:

先看看一个简单的例子:

 

分析以后继续。。。。。。。。