zoukankan      html  css  js  c++  java
  • IOCP在网络应用中常见错误分析

    IOCP在网络应用中常见错误分析

    原创文章 JohnsonFeng@yeah.net

    致力于网络游戏服务器.客户端引擎开发

    IOCP是一种异步套接字体机制,它是Windows系统中管理异步IO操作的API。使用IOCP,应用程序可以发送一个耗时的请求,然后执行其他的任务,而这个请求在内核执行,调用相应的驱动程序完成IO操作各个步骤。在大规模C/S架构的系统中,完成端口经常用于管理大量Socket连接。最近在一些网上代码和书店的部分参考书中,发现了一些常见的错误,这里经过简单总结,列出以下常见问题,供博友参考。

    1.错误处理已取消的ACCEPT完成通知

    在某些时候,应用层尚未对连入请求进行处理,这个连接还处于等待状态,如果在请求被处理前客户端由于某种原因断开了,那么GetQueuedCompletionStatus会返回FALSE。在此,某些参考书中对此返回值的处理是忽略,但这是错误的,首先,返回false并不表明完成端口出问题了,其次如果忽略,会导致一个ACCEPT异步请求丢失。通常,一个监听端口上,应用程序会创建很多个ACCEPT请求,以提高连接成功率。每当应用程序处理了一个连接请求时,应该再投递一个请求,以便完成端口总是在异步地接受连接,这样,在监听端口上进行的异步ACCEPT请求是固定的。如果应用程序经常因为GetQueuedCompletionStatus返回FALSE而忽略这些连接请求的完成结果,将会导致ACCEPT请求数减少,当这个数字减少到0之后,应用程序将得不到任何ACCEPT通知,也就是不会知道有客户端连入,当然,可能一开始还有少数客户端能连入,但是服务器端得不到通知,当连入排队数超出设置的上限(由listen函数设置)时,任何连入的请求都直接失败。此种错误本人已经在多本参考书和网上的文章中看到过,如果你的IOCPserver连不上,可能就是这种原因了。

    Tips:在连接请求队列满时,用Telnet连入,直接返回无法连接,这和端口没打开的表象是相同的,但是此时,在服务器端用netstat -a查看时,该端口却是打开的。

    正确的做法是,先关闭socket,然后再投递一个请求。

    2.完成端口适合短连接

      例如HTTP服务器,P2P Server等,实际上,很多场合并不需要IOCP,简单使用select模型就可以了,例如vsftp。

    3.memcpy使用不当

      这个memcpy如果拷贝的源范围和目标地址范围有重叠,将导致未决的错误,类似的错误也发生在strcpy中。正确的做法是用memmove;

    4.关闭Socket的时机

      一个连接被关闭,有多种情况:

      a.客户端主动断开,此时,需要注意,GetQueuedCompletionStatus可能因为断开返回一或两次,一般接受请求总是存在的,所以至少有一次是因为WSARecv异步调用返回;而WSASend可能在断开时没有发生,也可能正在进行,这时,会产生一次完成事件。所以,在处理这种情况时,需要判别是否有两次事件,避免第一次直接施放资源,第二次再视图关闭相关资源而导致服务器逻辑错误。

      b.服务器端主动断开,服务器主动断开,建议使用closesocket,然后交给情况a去处理。

      c.网络中断,有通知,这种情况的处理和a也是一样的。

      d.网络中断,无通知,由于TCP协议的特点,没有数据需要传输时,不发送数据,所以,如果一个客户端突然死机了,server端是无法知道的,除非有数据发送出去失败了。在没有数据发送时,一般说来,可以用两种方法进行处理,一是定时发送某个同步消息,当发送或对方处理失败时,就表明连接断开了;另外一种方法是经常地检测客户端有多长时间没活动了,如果超过一定时间就断开,当然客户端可还需要数据传输,那么再建立一次连接,例如http server就使用这种方式,当webbrowser打开一个网页后长时间停留,服务器可以在超过一定时间后断开以施放服务器资源。

     5.不正确地处理TCP数据流

      TCP数据是按流传输的,保证数据按顺序到达,但TCP并不保证数据按调用,逐个数据包进行传输,可能出现分解也可能出现合并,这是使用TCP的常识。

    如果在你的C/S程序中出现了不该出现的应用层消息,或者出现了连接不上的问题,或者出现了掉线频繁的问题,那么此文章可能对解决问题有所帮助。

    参考:

    GetQueuedCompletionStatus API文档 http://msdn.microsoft.com/en-us/library/aa364986(VS.85).aspx

    VSFTP(very safe ftp): http://vsftpd.beasts.org/

  • 相关阅读:
    POJ 1469 COURSES 二分图最大匹配
    POJ 1325 Machine Schedule 二分图最大匹配
    USACO Humble Numbers DP?
    SGU 194 Reactor Cooling 带容量上下限制的网络流
    POJ 3084 Panic Room 求最小割
    ZOJ 2587 Unique Attack 判断最小割是否唯一
    Poj 1815 Friendship 枚举+求最小割
    POJ 3308 Paratroopers 最小点权覆盖 求最小割
    1227. Rally Championship
    Etaoin Shrdlu
  • 原文地址:https://www.cnblogs.com/Tue/p/1544634.html
Copyright © 2011-2022 走看看