套接字缓冲区 - recv()

时间:2014-01-07 14:54:07

标签: c++ sockets blocking

试图了解阻塞套接字recv()。 阻止在客户端应用程序中实现的套接字并连接到服务器。 服务器应用程序中实现的IOCP非阻塞套接字。 客户端应用程序发送一些请求,服务器响应肯定或否定回复。有时服务器中的处理时间在同一毫秒内。一旦收到请求服务器应用程序立即响应。 处理大约400个请求/响应时,服务器应用程序以相同的毫秒响应,但客户端应用程序在5秒后收到。时间延迟。

我们尝试使用wireshark来分析延迟和观察的位置:

  1. wireshark时间戳和客户端app log timestamp.i.e之间存在5秒的时差。客户端应用程序日志比wireshark时间戳晚5秒。

  2. 我们发现recv()从套接字缓冲区读取数据的平均时间为15毫秒。

  3. 问题是由于阻塞套接字?  这是代码;

    int classA::ReceiveFullMessage(int sock)
    {
        int i=0, nRet;
        unsigned short *tmplen, pktlen;
        struct timeval tv;
        int g_RcvLen = 0;   
        bool bIsTimeOut = false;
        //HRESULT hr;
        char *hbInvokeId;
        char strMsg[2048];
    
        memset(g_RcvBuf,0,MAXMESSAGEPACKET);
        while (1)
        {
            // ***
            tv.tv_sec = bIsTimeOut ? 5 : 60; // Wait for 1 minute in normal case, if time out happens
            tv.tv_usec = 0;                  // Send heartbeat pkt and wait for 5 seconds for response
            FD_ZERO(&rdfs);
            FD_SET(sock,&rdfs);
    
            nRet = select(sock+1, &rdfs, (fd_set *)0, (fd_set *)0, (struct timeval *)&tv);
    
            //log mesg --returnValue[%d] receivedLength[%d], nRet, g_RcvLen
    
            if (nRet < 0)       {   
                //log mesgreturnValue = -1
                return -1;
            }
            else if(nRet == 0)
            {
                if(!bIsTimeOut)
                {
                    //Timeout happened, send heart beat
                    bIsTimeOut = true;
                    if (strlen(szServerIp) > 0) {
                        // send heart beat packet
                        hbInvokeId = SendRequest(szBuf, NULL);
                    }
                    else
                        hbInvokeId = SendRequest("<Echo>APIXport HB</Echo>", NULL);
                }
                else    {
                    //Timeout happened, No response for heart beat                      
                    m_packet[atoi(hbInvokeId)].inUse = false;
                    return -1;
                }
            }
            else if (nRet > 0)
            {
                bIsTimeOut = false; //***
                if(FD_ISSET(sock,&rdfs))
                {
                    if (g_RcvLen < 2)
                    {
                        //log mesg receivedLength[%d] < 2, g_RcvLen
    
                        // read header
                        nRet = recv(sock,&g_RcvBuf[g_RcvLen], 1, 0);
    
                        if (nRet <= 0)
                        {
                            // log mesg --Recvd Improper Header
                            return -1;
                        }
    
                        // receive two successive zeros..frame header
                        if (g_RcvBuf[g_RcvLen] == 0) g_RcvLen++;
                        else g_RcvLen = 0;
    
                        //log mesg receivedLength[%d] < 2 at --end returnValue[%d], g_RcvLen, nRet
    
                    }
                    else if (g_RcvLen < 4)
                    {
                        // log mesg --receivedLength[%d] < 4, g_RcvLen
    
                        // read length
                        nRet = recv(sock, &g_RcvBuf[g_RcvLen], 1, 0);
    
                        if (nRet <= 0)  {
                            //Recvd Improper Length
                            return -1;
                        }
                        g_RcvLen++;
    
                        //log mesg --receivedLength[%d] < 4 --end returnValue[%d]", g_RcvLen, nRet
                        logMsg(strMsg, VERBOSE);
                    }
                    else if (g_RcvLen >= 4)
                    {
                        // try to receive full packet
                        tmplen= (unsigned short*)&g_RcvBuf[2];
                        pktlen = ntohs(*tmplen);
    
                        nRet = recv(sock, &g_RcvBuf[g_RcvLen], pktlen-g_RcvLen, 0);
                        if (nRet <= 0)  {
                            //log -- Recvd Invalid Packet
                            return -1;
                        }
    
                        g_RcvLen += nRet;  // add only received number of bytes
    
                        //log mesg --receivedLngth[%d] >= 4 --end returnValue[%d], g_RcvLen, nRet
    
                        if (g_RcvLen == pktlen)
                        {
                            // full packet received
                            return (g_RcvLen); // exit with length
                        }
                    }
                }
            }
        }
        return g_RcvLen;
    }
    

0 个答案:

没有答案