skynet网络部分剖析(一) socket的状态

最近看了一些开源的网络库源码,有libevent,muduo,redis,类nginx等等。再看skynet网络部分就觉得很容易了,因为他们都是基于reactor模式,套路都差不多。不过skynet的网络部分要稍微复杂点,因为他最终要面向的是lua逻辑端。为了让lua socket api这块设计的合理,好用,整个网络架构上相比前面介绍的网络框架会有点绕,比方说socket的状态,比其他框架要多出几种来。

socket状态有哪些呢?查看定义如下:

#define SOCKET_TYPE_INVALID 0
#define SOCKET_TYPE_RESERVE 1
#define SOCKET_TYPE_PLISTEN 2
#define SOCKET_TYPE_LISTEN 3
#define SOCKET_TYPE_CONNECTING 4
#define SOCKET_TYPE_CONNECTED 5
#define SOCKET_TYPE_HALFCLOSE 6
#define SOCKET_TYPE_PACCEPT 7
#define SOCKET_TYPE_BIND 8

我们看到listen之前还有个plisten,没有accept,却有paccept。这个前缀p是什么意思呢?

要想解释这个,先得说说lua socket api如何设计和使用。一个典型的socket处理如下:

    local id = socket.listen('127.0.0.1', 8876)
    local acceptFun = function(id, addr)
                print('connnect from '..addr..' '..id)
                socket.start(id)
                while true do
                    local ret = socket.read(id)
                    print('ret is ', ret)
                end
            end
    socket.start(id, acceptFun)

在lua逻辑中,我们不能像写c服务器那样,listen之后调用在while循环中调用accept等待客户端连接,我们必须善用脚本语言的回调。感谢云风大侠设计出如此优秀的方案,在sockt.start中接受用户连接的回调函数。

这里的socket.start相当于要打开了一个socket,可是按照一般的网络框架理解,listen不正是打开了一个监听的socket吗。所以云风的设计方案是,listen底层确实建立了一个监听socket,但是他还没有纳入epoll的监管之中。等到socket.start才将监听socket纳入epoll的监管,所以在此之前,监听socket的状态是SOCKET_TYPE_PLISTEN,等到socket.start之后变为SOCKET_TYPE_LISTEN。

同理,当有客户端连接时,会生成一个新的连接socket,此时的状态为SOCKET_TYPE_PACCEPT,注意此时也不会将该socket纳入epoll的监管之中。等到调用socket.start之后状态变为SOCKET_TYPE_CONNECTED,同时将该连接socket纳入epoll的监管中。

总结一下,要想启用socket服务,lua调用socket.start必不可少,他都是将监听的socket或连接的socket纳入epoll的监管之中,在lua逻辑端会使所在服务暂停,等待连接或发送消息。然后他会给所在的服务发送类型为SKYNET_SOCKET_TYPE_CONNECT的socket消息。lua逻辑收到该消息的处理方式是恢复服务,服务得以继续进行。

在lua逻辑中充当客户端的角色时,要调用id = socket.open(ip, port),此时底层会去connect服务器,成功后连接socket的状态为SOCKET_TYPE_CONNECTED。这种情况可以不用调用socket.start(id),为什么呢,难道不需要将socket纳入epoll的监管吗?其实在处理open消息,建立新的socket时已经将其纳入epoll的监管中了,new_fd(ss, id, sock, PROTOCOL_TCP, request->opaque, true),最后一个参数为true,表明要加入epoll中。

当socket收到消息(关闭消息也算)或有错误产生时,skynet则没有给出socket的状态,只是将收到的数据push到服务的消息队列。



猜你喜欢

转载自blog.csdn.net/zxm342698145/article/details/81012582