skynet网络剖析
1.tcp
2.epoll
3.socket线程
4.gate服务
5.netpack 解包打包
6.service_gate.c 原理
数据流大概如下
thread_socket --> skynet_socket_poll -->forward_message
skynet_start.c
skynet节点启动时会启动一个线程专门处理socket事件
检测epoll事件
forward_message里 将tcp数据留发送到对应的服务的消息队列(即aocor的消息队列,一般是gate服务)
socket服务是怎么知道这条消息要往哪个服务发送呢?
在socket_server.c new_fd会把通过epoll_ctl add 将服务标识添加到 rbtree的event当中,这样就映射起来了
socket_server.c
socket_poll.h
socket是怎么检测有数据的呢?
socket_server.c
sp_wait返回事件的数目,并将触发的事件写入events数组中。
然后 forward_message_tcp 调用 read 把数据读出,每次从内核读出来的数据一开始是64个字节。
gate服务与netpack包解析
gate服务与agent中间还有个watchdog,数据进来会先到gate,gate会给watchdog发送一个请求,watchdog收到请求会启动一个agent。agent启动后会给gate发送请求forward。之后数据直接就gate发给agent,不经过watchdog。
这里主要将gate如何解析tcp数据流转化为应用层数据。
gate服务解包会调用c函数netpack.filter
filter_data 把type、 fd、 组装好的data(ligthuserdata)、size 返回
组装好的数据最终变成msg发送给服务处理
“more”:表示收到的数据不止一个tcp包,netpack.filter会把包依次放到队列里,然后回调函数一个个从队列中pop出来
这里贴上其它博客内容https://www.cnblogs.com/cnxkey/articles/15945319.html
这里讲到非常详细
主要数据结构 链表
当从内核tcp流读出的数据有两个包的数据的时候 是通过以下的递归来分隔一个个完整的逻辑数据包
service_gate.c是废弃的gate服务
与netpack分包类似,c的gate服务是用databuff这个ringbuff(环形buff)来进行分包的,把数据流分成一个个完整的包。
gate结构存了一个conn数值,conn存在databuffer
gate结构还存了一个环形队列 messagepoll
databuffer_push,就是把data放进环形队列。把databuffer和mp链接起来
环形队列初始化
另外一种分包模式,一个tcp一个服务
https://blog.codingnow.com/2016/03/skynet_tcp_package.html