为什么我的其他条件永远不会执行?

时间:2014-03-03 13:34:12

标签: c++ udp

我正在使用UDP服务器,除了else条件之外,这个UDP服务器代码工作正常。可能是我错了,但我已经做了很多事情使用else条件以相同的方式终止while循环。我不确定它的UDP问题或其他什么........

while(1)// execute three times because its getting data only three times from the client
    {
    int total_bytes = 0;
    int bytes_recv=0;
    int count = 0;
    std::vector<double> m_vector(8000);

        // Bytes are also received 3 times correctly then why else condition not executing after receiving 3 times ?
         bytes_recv = recvfrom(Socket,(char*)m_vector.data(),64000,0,(SOCKADDR*)&ClientAddr,&i);
        count++;

        if(bytes_recv > 0 )
        {
            total_bytes = total_bytes+bytes_recv;
            std::cout<<"Server: loop counter is"<<count<<std::endl;
            std::cout<<"Server: Received bytes are"<<total_bytes<<std::endl;
        }else

        {
        //why this part  never executes ? 
            std::cout<<"Data Receiving has finished"<<std::endl;
            break;
        }
    }

    WSACleanup();
    system("pause");
    return 0;
    }

3 个答案:

答案 0 :(得分:1)

来源中的评论表明,您只希望来自客户端的3个数据报。因此,请计算您收到的数据报数量,如果您已经有3个数据报,则不要继续调用 recvfrom
您已经有一个变量count,但每次迭代都会重置为零,并且不会用作退出条件。

拥有count == 3后,知道没有其他内容,所以调用recvfrom毫无意义。它只会阻止,因为这就是你要告诉它的事情。使套接字无阻塞将“帮助”避免阻塞,但随后你将进行轮询,这也不好(并且没用,因为你知道没有任何东西可以接收)。最好正确操作

您也可以让客户端发送“消息结束”数据报,但当然您必须添加超时和丢包策略,否则服务器可能会永久阻止 。不仅是因为恶意客户端,还因为接收缓冲区已满并且数据包被丢弃(这是正常情况!)。

或者,由于您的代码中调用了WSACleanup,因此您正在使用Winsock。这意味着可以使用重叠的WSARecvFrom代替recvfrom。触发一个接收,并从其完成处理程序触发另外两个,也具有回调函数。在触发请求之后,忘记它并让回调处理其余的,你现在可以处理另一个客户端(必须是警报但是要发生这种情况......或者,阻止IOCP或WaitOnMultipleObjects或其他)。
如果在这么久之后没有第二个或第三个数据包进入,请发送“请重新发送”消息或考虑客户端死机,关闭套接字并继续。

答案 1 :(得分:0)

recvfrom默认为阻塞调用,只有在读取数据包后才会返回。因此,当您停止发送数据包时,它只会在recvfrom上阻塞,因此0字节的情况永远不会发生

您可以将标志更改为recvfrom以更改此行为,但它可能不是您想要的,因为如果在发送数据包之间有任何延迟,您将获得0个字节并退出。

我想你可以看到你没有收到任何数据包然后关闭了多久,所以在其他情况下你可以在退出前使用计时器和一个运行总计。

你想要完成什么?

答案 2 :(得分:0)

我没有检查过(坏我,我知道,但时间很短),如果recvfrom遵循典型行为,那么它可以保证:

  • 返回值&lt; 0表示错误
  • 返回值== 0表示一切正常,但频道无法再收到任何内容
  • 返回值&gt; 0表示已收到某些内容

在TCP中,只有在连接关闭时才会收到“收到的字节数”== 0。

在UDP中没有“连接”这样的东西。该频道随时可以接收,直到你的 socked关闭。

因此,它可能只是等到有东西到来。它无法检测到没有人可以收听。这是UDP的细节。

如果你想在长时间没有任何东西的情况下捕获一个案例,请尝试设置读取超时。