freshbug's notes

freshbug的代码人生

bekilledlzyID:bekilledlzy
14154次访问,排名7782(-1)好友0人,关注者0
bekilledlzy的文章
原创 17 篇
翻译 0 篇
转载 32 篇
评论 6 篇
freshbug的公告
访问www.freshbug.com
自2007年10月16日
freshbug的联系方式:
freshbug@gmail.com
最近评论
loadend:你好,我想问一下,那注册google ad帐户的时候不是要填网址嘛,填什么呢?是不是填http://blog.csdn.net/用户名/??
freshbug:stl里面有一些静态变量 不能跨dll vector有时候能跨dll是因为连续的内存分布

跨模块传输数据最好是能用C风格的结构 用C++类很容易出问题
wang:我是向dll中传一个map指针,结果也是it++之后就内存泄漏
wang:我也遇到了类似问题。
远离尘嚣:老大,能把你的Uft8ToAnsi是自定义的转码函数共享一下嘛?万分感谢!
文章分类
收藏
    相册
    who's freshbug?
    技术站点
    老牛们的blog
    咨讯
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    转载 编写大容量和健壮的服务器系列—处理IOCP连接关闭收藏

    新一篇: [转载]一个关于IOCP本身的陷阱 | 旧一篇: .asx是什么文件?

    编写大容量和健壮的服务器系列—处理IOCP连接关闭

     

     

    邓立波 深圳,2007-8

    作者联系方式:

    email:         libodeng@gmail.com

    msn:           libodeng@gmail.com

    tel:              13510275799

    版权所有(C) 2007 邓立波. 保留所有权利

    警告:未经作者许可,任何人或组织不得转载,公开发布,拷贝,传播本文献的全部或部分。

     

    及时监测连接被动关闭

           除非有特别要求,否则你应该总是对每个连接保持一个挂起的接收pending io

    (使用WSARecv投递)。如果用户主动关闭连接,你的GetQueuedCompletionStatus调用将返回成功,但接收到的数据长度为0,你能根据这点检测连接是否已被对方关闭。如果连接被重置或者io被取消(如果你调用了CancelIo的话),GetQueuedCompletionStatus将返回失败,注意这时还应该判断GetQueuedCompletionStatus调用返回的lpOverlapped值,如果该值不为NULL,说明iocp已经检测到一个连接已经中断。

     

    安全的关闭连接

           很多人写的服务器网络库有一个难以接受的缺陷(包括我曾就职公司的一些同事),当服务器程序主动关闭连接时,刚发往客户端的包有时出现丢失,这时他们推荐的方式往往是发送数据后等待几秒再关闭连接。豪无疑问,这是一种笨拙的实现方式,他们遇到的问题根源是什么呢?

           在非IOCP模式网络程序中,你只要简单的调用closesocket函数就可以确保数据在操作系统释放socket之前安全到达对方,但在IOCP模式下,如果调用closesocket时有未决的pending IO将导致socket被重置,所以有时会出现数据丢失。正统的解决方式是使用shutdown函数(指定SD_SEND标志),注意这时可能有未完成的发送pengding IO,所以你应该监测是否该连接的所有是否已完成(也许你要用一个计数器来跟踪这些pending IO),仅在所有send pending IO完成后调用shutdown

    当你调用shutdown时,也许数据仍然停留在操作系统的缓冲,操作系统将在数据发送完后发出一个FIN包来启动关闭进程,客户端接收完数据后,将接受到一个0长度的包,以此判断连接已关闭(你写的客户端肯定有检测连接关闭,不是吗?),然后调用closesocket,这时服务器的GetQueuedCompletionStatus将接收到一个数据长度为0的包,这时你就可以调用closesocket,并释放相关连接资源。

    在绝大部分情况下上述的过程连接能完美的关闭。如果你特别注重服务器的安全性和健壮性,可能你还需要做一个“连接关闭队列”,对每个已调用shutdown的连接放到这个队列,然后定时的对这个队列扫描,如果一个连接5秒(你也可以自己调整)还不能关闭,那么就强制关闭它。

     

    处理大并发短连接时如何避免TIME_WAIT状态

           关于如何避免TIME_WAIT这个问题,一直没看到有效的处理方式(至少我没有),

    我将这里披露一种有效的方式。回到上一段,我们最后调用了closesocket关闭连接,这时仍然可能出现TIME_WAIT状态,但注意这时所有的数据都已经传输完毕,因此你可以强制关闭socket避免服务器连接进入TIME_WAIT(这时只会发出连接重置 RESET包)

    //立即关闭(避免出现TIME_WAIT状态)

                  LINGER linger = {1,0};

                  setsockopt(socket, SOL_SOCKET, SO_LINGER,

                         (char *)&linger, sizeof(linger));

     

     

    socket唯一性问题

    正常情况下 SOCKET套结字值是唯一的,但是操作系统在分配socket值时有随机性,最近关闭的socket值可能重新分派给一个刚刚建立的新socket.,尤其在大连接数的情况下。所有在编写网络库时需要注意socket唯一性问题,例如应该避免多次对同一个套结字调用closesocket

    发表于 @ 2007年08月16日 16:30:00|评论(loading...)|编辑

    新一篇: [转载]一个关于IOCP本身的陷阱 | 旧一篇: .asx是什么文件?

    评论:没有评论。

    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © freshbug