从ACE源代码库看Socket编程应该怎么写

来源:互联网 发布:开展网络公益活动总结 编辑:程序博客网 时间:2024/05/01 16:17
       我的同事和我说,传说中神乎其神的程序员很多,但未必有很多人会写Socket编程,我曾经不以为然。我曾经看过不少Socket编程的Demo,也就认为Socket编程也就这样了。但或许我错了。我的同事告诉我,socket编程和高效socket编程是两码事,我也不以为然。我曾经很鄙视微软RPC。所有的一切一切证明我都错了。
       错误的原因在于我看到了ACE的源码。下面是一个片断:
ssize_t
ACE::recv_n_i (ACE_HANDLEhandle,
              void *buf,
               size_tlen,
               intflags,
               size_t *bt)
{
 size_ttemp;
 size_t &bytes_transferred = bt == 0 ? temp : *bt;
 ssize_tn;
 
 for (bytes_transferred = 0;
       bytes_transferred < len;
       bytes_transferred += n)
    {

      // Try to transfer as much of the remaining data as possible.

      n = ACE_OS::recv (handle,

                        (char *) buf + bytes_transferred,

                        len - bytes_transferred,

                        flags);

      // Check EOF.

      if (n == 0)
        return 0;
 

      // Check for other errors.

      if (n == -1)
        {

          // Check for possible blocking.

          if (errno == EWOULDBLOCK)
            {

              // Wait for the blocking to subside.

              intresult = ACE::handle_read_ready (handle,

                                                   0);

 

              // Did select() succeed?

              if (result != -1)
                {

                  // Blocking subsided. Continue data transfer.

                  n = 0;
                  continue;
                }
            }
 

          // Other data transfer or select() failures.

          return -1;
        }
    }
 
 returnstatic_cast<ssize_t> (bytes_transferred);
}
如果收到0,代表对端主动断开连接,这时候返回0;但是如果是-1的话,就需要仔细斟酌了。ACE没有武断地返回,而是检查了错误原因。如果Socket没有Block住的话,就会返回error,原因是EWOULDBLOCK;这时候ACE试图select,看看能不能读,如果可以读的话,就会继续读取。
如果以前我写Socket程序,我会这么写么?不会。因为我没有对Socket掌握的那么透彻,我相信也许很多传奇也不会写。
顺被说一句很可笑的事情,我以前不知道怎么处理网络收包错误导致网络包字节错位的问题,现在总算想明白了,直接把socket断开重连就可以了。以前,中兴的彩铃平台就是这样做的,我当时没有领会这样的好处。