Golang对TCP网络的处理(协程结合socket)

基础

TCP层之下都是一个不可靠的传输
TCP层开始可靠

我们开发者不想去关注三次握手四次挥手,去维护状态之类的
只想关注中间的数据传输,所以操作系统给我们提供了一个socket
每次三次握手之后系统就帮我们生成了一个 socket,只操作socket就行

linux中socket以文件描述符FD作为标识,同样FD可能也是其他的标识

客户端调用connect ,close 三次,四次挥手
sever中socket的个数 = 1个监听的 + 已建立连接的
服务端同时关注多个已建立连接的socket就诞生了 IO模型(同时操作socket的方案)

3个方案(阻塞,非阻塞,多路复用)

阻塞IO
多个线程同步读写socket,线程陷入内核态,一直阻塞等待数据
当读写成功后,切换为用户态,继续执行业务
开发难度小,代码简单
内核态切换开销大(与用户态不断切换)

非阻塞IO

业务不断地去轮询socket,看那个有业务过来,socket不会卡住
不会陷入内核态,在用户态(业务)
理论上在一个线程执行操作,相对之前的阻塞socket,编码要求会高

epoll多路复用

event poll (事件池)(监听),返回发生的事件列表,业务直接去调用相应的socket
监听事件的任务从业务转移给了操作系统

go抽象epoll
netpoll network poller

go的网络层实现了基于协程和socket结合,隐去了epoll这一层
epoll抽象层是为了统一各个操作系统对多路复用器的实现

epoll_create 新建复用器,_ctl 插入监听事件 _wait 等待返回列表

init() 新建epoll,并拿到FD文件描述符
polldesc记录了协程和sicket的对应关系

netpoll 传出的是一个协程列表,协程可读,可写
先调用 _wait 然后结合 polldesc 返回列表

network poller

初始化:原子操作判断是否重复,调用init()
pallcache 列表头 有Lock 缓存polldesc(description)
rg,wg表示想读或者写这个socket的地址
go:linkname 小写方法调用
新增
分配后初始化,调用封装不同平台的open方法

socket已经可读写
gc是不断的循环跑的一个东西

除了业务之外的系统,gc
都是调用的g0协程 ,在g0栈上操作
runtime循环调用netpoll ,(g0)

go如何抽象epoll

socket底层通信过程
建立连接,通信,关闭

目前涉及到net包对TCP网络操作的抽象
net.Listen
新建socket,并执行Bind(绑定端口)
新建一个NetFD(net包对 sicket的描述)
NetFD 其中有一个 polldesc
整个方法返回一个TCPListener对象
同时将FD加入监听
TCPListener本质上一个listen状态的socket
socket(Lieten)socket(established)

只有一行的方法可能是汇编,也可能是go link
TCPListener调用其Accept得到socket(established)

goroutine - per - connection
一个协程一个连接的编程方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值