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

全部博文(100)

文章存档

2011年(5)

2010年(12)

2009年(83)

分类:

2009-12-22 10:58:41

mangosd 之 Patcher

     在mangos的登录进程realmd中还有一个下载补丁的功能。用户登录的时候会附带自己的版本号,realmd会检查这个版本号,如果不是当前合法的版本号且服务器上有用户版本的补丁,那么就给用户一个响应,让其来下载对应补丁;响应中包括了补丁文件的md5和文件大小等信息。
    客户端请求下载补丁的时候,realmd会为这个用户启动一个线程;在这个线程中,服务器会不断向用户推送补丁包文件数据,直到发送完毕,看看代码:
/// Send content of patch file to the client
void PatcherRunnable::run()
{
    XFER_DATA_STRUCT xfdata;
    xfdata.opcode = XFER_DATA;
    while(!feof(mySocket->pPatch) && mySocket->Ready())
    {
        ///- Wait until output buffer is reasonably empty
        while(mySocket->Ready() && mySocket->IsLag())
        {
            ZThread::Thread::sleep(1);
        }
        ///- And send content of the patch file to the client
        xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch);
        mySocket->SendBuf((const char*)&xfdata,xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize));
    }
}
    比较有意思的地方是,如果服务器发现网络“卡”的时候,就休息1秒为间隔休息,是这样判断“卡”的:
/// Check if there is lag on the connection to the client
bool AuthSocket::IsLag()
{
    return (TCP_BUFSIZE_READ-obuf.GetLength()< 2*ChunkSize);
}
     即发送的缓冲区中(CircularBuffer)中的空闲空间小于2*ChunkSize,而ChunkSize是每次从补丁文件中读取的数据块大小。即服务器发现缓冲区中放不下两次读取的数据时,就停下来休息,直到空间可用。
阅读(1717) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~