• idnemo

  • 致力于游戏开发~~
  • 首页
  • 碎语
  • 登录
  • select模型:妓女和嫖客的故事(一)

    post by idnemo / 2007-11-12 13:05 Monday

    winsock API中的两个函数recv()和send()都是阻塞式的,这种通信效率是很低的。
    举这么一个例子吧,从前有一个妓女和一个嫖客,这个嫖客呢每天都要逛窑子和那个妓女OOXX。所以那个妓女每天就在门口等待嫖客的到来,若嫖客没来,她也一直傻等在那里。即便有其他嫖客想来,妓女也不带理的。
    这就是阻塞式的方式,阻塞式的意思就是函数若没有执行成功,则不返回。这是大多数函数的做法,但是对于通信中的recv和send来说,这种方法是十分低效的,因为这两个函数会使得整个线程都阻塞住,无法做其他事情。就好比那个傻等嫖客的妓女一样。
    那么为什么通信程序要使用I/O模型?I/O模型就是应用程序提供一个缓冲区,在缓冲区进行收发数据。如果函数recv和send没有执行成功,则函数立即返回,线程可以先做其他的事情。等下次有数据要收或要发时,再执行函数。这样的函数就是非阻塞式的。
    也就是说,当那个妓女看到嫖客没有来时,她可以采取一些行动,来增加她的接客效率。这,就是I/O模型。微软为了提高妓女的接客效率,一共提供了5种I/O模型。
    这次说说最简单的select模型。select模型的核心就是select函数,它的原型是:
    int select(int nfds,
     fd_set FAR* readfds,
    fd_set FAR* writefds,
    fd_set FAR* exceptfds,
    const struct timeval FAR* timeout);
    第一个函数可忽略,置0即可。第二个是设读集(其实就是读取缓冲区中的数据),对应recv()函数用。第三个设写集,对应send()函数用。第四个设带外数据,一般用于查看错误。第五个是设置等待时间,这个参数比较重要。下面是一个封装了select模型的函数:
    int ClientStartRecv(char *recvBuffer,int bufLenth)
    {
     fd_set recvset;
     TIMEVAL timeout;
     timeout.tv_sec=0;
     timeout.tv_usec=0;
     int recvByte=0;
     FD_ZERO(&recvset);
            FD_SET(appClientSocket,&recvset);
         
     int ret=select(0,&recvset,NULL,NULL,&timeout);
     if(ret>0 && FD_ISSET(appClientSocket,&recvset))
     {
      recvByte=recv(appClientSocket,recvBuffer,bufLenth,0);
      
     }

     return  recvByte;
     
    }
    从这里也可以看出,select模型还是比较容易使用的。这里重点说说timeout这个参数,如果这个参数设置成(0,0),那么recv函数在发现没有数据可读时,就立即返回。如果设置成一个大于0的值,则recv函数等待相应的时间后返回。如果timeout是一个空指针,则函数变成阻塞式,直到至少一个描述符正好碰到指定的条件为止。那么这个参数具体要设置成多大的数值最好呢。
    还是以刚才的例子来说明:妓女在发现嫖客没来的时候,立刻回房,过了一会儿,又去门口看看嫖客来了没有,如此反复。将参数设置成(0,0)就会这样。
    如果设置一个等待时间,那么妓女就会在门口等待一段时间,如果嫖客没来则回房。过了一会儿,又去门口看看嫖客来了没有,如此反复。将timeout设为大于零的值就是这样。
    如果是空指针,妓女则在门口一直等待,然后看到任何一个看似嫖客样子的人,就将其拉去OOXX。这个就是将timeout设成空指针的形式。这是很危险的,因为你怎么知道这个看似嫖客的人有没有病或者不是强盗、或者没钱的人。很显然,这个随便拉来的客人并不是妓女本身想要的。
    说了那么多,其实我也不知道timeout该设多少。我的前辈跟我说timeout设(0,0),而《windows网络编程技术》这本书则说应该尽量避免这样设置,因为会这样的设置会让select变成轮询操作,使其效率变低。实际上,MSDN并没有这么说,所以我都是设成(0,0)。

    这里开源一个前些天完成的一个通信lib,用的就是select模型写的。我的编译环境是VS2005,更低的版本VC只要拷贝.h和.cpp,然后自己新建一个库项目,将两个文件放入工程中,重新编译一下就可以了。
    我曾经对别人写好的lib和class很依赖,现在想来还是自己写的东西最好,即便有BUG,调试起来也知道该怎么入手。反观用现成的lib,如果它是成熟的,那么可能会增加开发效率。如果是一些不成熟甚至本身有bug的库,那么只能增加调试程序的负担。所以用别人的库写程序前,还是要先想想清楚先的。至少这个库得是开源的,可以清楚的看到它的代码实现。

    另外,以后我要继续用妓女和嫖客的例子来说明其他4种I/O模型。我觉得这便于自己的理解,哈哈。

     

     

     

     

     

    附件下载:
    comSocketLib.rar 2.13MB
    标签: 游戏开发
    « TCP和UDP:妓女和嫖客的故事(二) | 本周高挂免战牌»

    引用地址:

    评论:

    idnemo
    2007-11-18 09:46
    tcp记住一点就可以了:它不会丢数据。如果丢了数据,就是编程的问题
    fei
    2007-11-16 14:08
    我最近也在弄WINSOCK这快,头有点乱.还得强烈的冲电呀.其实我一点都不明白这WINSOCK,但没办法,没有时间学习,直接就弄了,到最后我也算明白怎么个回事.打算周未好好整理下.TCP/IP是个难点.

    发表评论:

  • blogger

      blogger
    • idnemo
    • 目前供职于2k Games,Take-Two的子公司。非常荣幸为这样的公司工作。 MAIL:shenheshen@163.com QQ:64183074 MSN:idnemo@hotmail.com
  • 标签

    • 游戏 牢骚 音乐 电影 游戏开发 足球
  • 日历

  • 随机日志

    • 记录下这个幸福的日子
    • C++与C#的不同(三)
    • 任天堂,索尼还有微软
    • 近况,还有一年的总结
    • 梦想实现的一刻……
    • 用PSP完美阅读PDF书籍
    • 丑陋的中国人
    • 警告
  • 最新碎语

    • The submarines的 vote,好听!

      2008-11-02 07:42

    • 换了背景音乐

      2008-08-10 05:15

    • 欧洲杯,只有周末能看了

      2008-06-18 13:31

    • 悼念死者。

      2008-05-18 11:48

    • 弄了个Skype,可以用本本和PSP打电话了

      2008-05-10 06:01

    • 更多»

  • 最新评论

    • 丁字裤
      强人呀!
    • 淘宝网批发
      武汉挺好的,哈哈
    • 最好的减肥药
      还没看
    • Wikipedia YouTube
      A Ss was incredible? http://en.wikipedia.org/wiki/Youtube - Wikipedia YouTube <a href="http://en.wikipedia.org/wiki/Youtube">Wikipedia YouTube</a>
    • 美国优洛
      看了,还可以
    • 农民
      “Get a Room.”让我想起那年夏天,在中山,牵着女朋友每到一处都说没房。
    • 西安seo
      武汉没去过,相比于深圳如何呢?
    • zuoteng
      遇到你碰巧是我人生中最诡异的一段时间。
    • 白衣大葛格
      好有深度啊。。。唉。我俗人。。。
    • acboy
      i like it
    • 宝鸡seo
      造型实在令人失望!
    • idnemo
      靠,被垃圾评论淹没了
    • idnemo
      靠。
    • 小 .xin
      强势插入!留痕~~~
    • vinci
      帅啊!
  • 链接

    • emlog
    • 我的豆瓣
  • 存档

    • 2010年7月(1)
    • 2010年6月(1)
    • 2010年5月(1)
    • 2010年4月(3)
    • 2010年3月(1)
    • 2010年2月(3)
    • 2009年11月(1)
    • 2009年10月(1)
    • 2009年9月(3)
    • 2009年8月(1)
    • 2009年4月(1)
    • 2009年3月(1)
    • 2009年2月(2)
    • 2009年1月(1)
    • 2008年12月(1)
    • 2008年11月(1)
    • 2008年10月(2)
    • 2008年9月(1)
    • 2008年8月(4)
    • 2008年7月(2)
    • 2008年6月(4)
    • 2008年5月(5)
    • 2008年4月(4)
    • 2008年3月(4)
    • 2008年2月(4)
    • 2008年1月(4)
    • 2007年12月(5)
    • 2007年11月(5)
    • 2007年10月(5)
    • 2007年9月(7)
  • 搜索

  • 信息

    • 日志数量:79
    • 评论数量:172
    • 引用数量:3
    • 今日访问:196
    • 总访问量:322663
  • 豆瓣

订阅Rss
Powered by emlog