Chinaunix首页 | 论坛 | 博客
  • 博客访问: 329780
  • 博文数量: 100
  • 博客积分: 2620
  • 博客等级: 少校
  • 技术积分: 920
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-16 02:50
文章分类

全部博文(100)

文章存档

2011年(5)

2010年(12)

2009年(83)

分类:

2009-12-06 16:40:27

Mangos 之 AuthSocket模块

(1)AuthSocket从TcpSocket继承而来,在TcpSocket中处理具体的网络读写任务(OnRead),将数据读入并存放到循环缓冲区,然后AuthSocket的OnRead()会将循环缓冲区中的
数据解析出来并调用响应的处理函数处理。
(2)mangos在TcpSocket中采用循环缓冲区来存放接收到或待发送出去的数据,所以也要进行crosses circular border处理。这样只有在跨越边界的时候,才会多调用一次memcpy;
    另外一种处理方式是每次将数据移动到缓冲区头部,其实这样可能会导致更多的memcpy调用,效率应该不如前一种方式。
    在向循环缓冲区中写数据时,如果循环缓冲区中空间不够,数据将被丢弃,而不放入缓冲区中。我想到了一种极端情况,比如缓冲区中哈剩下20字节空间,而新的用户数
据来了,数据包的大小是30字节,由于网络原因被分包发送过来了,先到了15字节,这时剩余空间可以放下这15字节;而另外半个包之后猜到,这时缓冲区中已经没有空间了,所
以后半个包就将被丢弃;这时缓冲区中的包就不完整了。
    其实,这个问题可以通过一种简单方式进行处理,即调用recv时,就将最大的接收字节数设置成循环缓冲区的空闲空间大小,但是mangos没有这么做。
(3)在Auth模块中的协议有多种,mangos将协议码和处理函数指针放到一个结构中统一管理,如:
typedef struct AuthHandler
{
    eAuthCmd cmd;
    uint32 status;
    bool (AuthSocket::*handler)(void);
}AuthHandler;
定义:
const AuthHandler table[] =
{
    { AUTH_LOGON_CHALLENGE,     STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge},
    { AUTH_LOGON_PROOF,         STATUS_CONNECTED, &AuthSocket::_HandleLogonProof    },
    { REALM_LIST,               STATUS_AUTHED,    &AuthSocket::_HandleRealmList     },
    { XFER_ACCEPT,              STATUS_CONNECTED, &AuthSocket::_HandleXferAccept    },
    { XFER_RESUME,              STATUS_CONNECTED, &AuthSocket::_HandleXferResume    },
    { XFER_CANCEL,              STATUS_CONNECTED, &AuthSocket::_HandleXferCancel    }
};
调用:
if ((uint8)table[i].cmd == _cmd &&
 (table[i].status == STATUS_CONNECTED ||
 (_authed && table[i].status == STATUS_AUTHED)))
{
   if (!(*this.*table[i].handler)())
   {
     return;
   }
}
    在AuthSocket的OnRead函数中,只会把第一个字节取出来,即协议命令的类型,然后更加协议命令在table中找到对应的处理函数接口,在具体的协议处理函数中,处理函数根据自己的协议体规范从循环缓冲区中读数据并做处理。
    我们自己的做法通常是有一套协议解析,编解码函数,会把完整的协议体解析出来,然后根据具体的协议类型调用不同的函数来处理;但是在这里,mangos没有采用这种方式,而是只在公共的部分解析大家公共的cmd信息,其他具体的信息,甚至包括协议体长度这些私人东西都交给具体的处理函数来解决,有点“个人自扫门前雪”的感觉,但是这样有一个好处就是在需要添加协议的时候,我只需要实现新的协议的解析处理接口,并在table中添加一项即可;如果采用专门解析协议体的方式,那么就会多修改一个地方,即在协议解析的代码部分需要加入新协议的解析,处理部分也需要加入新的代码,多了一个修改的地方,多了一个烦恼,也多了一个出错的可能。
(4)mangos怎么判断网络卡的?
“TCP_BUFSIZE_READ-GetOutputLength()< 2*ChunkSize”
TCP_BUFSIZE_READ是网络连接循环缓冲区最大长度(16400Bytes),
GetOutputLength()表示当前发送缓冲区中累计了多少字节没有发送出去。
ChunkSize 2048Bytes
即当前发送缓冲区中的空闲空间小于2个ChunkSize就认为网络卡了。
阅读(1508) | 评论(0) | 转发(0) |
0

上一篇:模板特化

下一篇:linker & loader 之一

给主人留下些什么吧!~~