Winsock recv() 不阻塞

发布于 2024-10-02 08:14:36 字数 917 浏览 4 评论 0原文

我刚刚编译了这段代码: http://www.win32developer.com/tutorial/winsock/winsock_tutorial_2.shtm

我添加了一些代码,以便它在无限循环中执行recv()。我的问题是,如果没有数据读取,它仍然不会阻塞。

如果我认为 recv 应该在我的情况下阻塞,我是完全错误的吗?

我添加的代码是:

for(;;)
{
  char buffer[1000];
  memset(buffer,0,999);
  int inDataLength = recv(Socket,buffer,1000,0);

  int nError=WSAGetLastError();
  if(nError!=WSAEWOULDBLOCK&&nError!=0)
  {
    std::cout<<"Winsock error code: "<<nError<<"\r\n";
    std::cout<<"Client disconnected!\r\n";

    // Shutdown our socket
    shutdown(Socket,SD_SEND);

    // Close our socket entirely
    closesocket(Socket);

    break;
  }
}

它位于末尾,在 std::cout<<"Client returned!\r\n\r\n"; 行之后。 我知道我从“非阻塞”示例中复制了此代码,但我认为这段代码不应该真正执行任何非阻塞操作,但我的 for 循环仍然疯狂运行!

I have just compiled this code:
http://www.win32developer.com/tutorial/winsock/winsock_tutorial_2.shtm

I have added some codes so it does recv(), in an infinite loop. My problem, if there is no data to read, it still does not block.

Am I totally mistaken if I think recv should block in my case?

The code I have added is:

for(;;)
{
  char buffer[1000];
  memset(buffer,0,999);
  int inDataLength = recv(Socket,buffer,1000,0);

  int nError=WSAGetLastError();
  if(nError!=WSAEWOULDBLOCK&&nError!=0)
  {
    std::cout<<"Winsock error code: "<<nError<<"\r\n";
    std::cout<<"Client disconnected!\r\n";

    // Shutdown our socket
    shutdown(Socket,SD_SEND);

    // Close our socket entirely
    closesocket(Socket);

    break;
  }
}

It is at the end, after the std::cout<<"Client connected!\r\n\r\n"; line.
I know I copied this from a "non blocking" example, but I dont think this code should do anything nonblocking really, still, my for loop is running like mad!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一袭水袖舞倾城 2024-10-09 08:14:36

recv 默认情况下应该是阻塞的,除非出现套接字错误或者您显式地将套接字设置为非阻塞。请务必检查返回值是否有错误。有关详细信息,请参阅有关 recv

recv should block by default, unless there's a socket error or you explicitly set the socket to non-blocking. Be sure to check the return value for error. For more information see the Microsofts MSDN article on recv.

不美如何 2024-10-09 08:14:36

循环未正确检查错误。它需要更像这样:

char buffer[1000]; 
int inDataLength;

do 
    {
    inDataLength = recv(Socket, buffer, sizeof(buffer), 0); 
    if (inDataLength > 0)
        {
        // inDataLength number of bytes were received, use buffer as needed...
        continue;
        }

    if (inDataLength == 0)
        {
        std::cout << "Client disconnected!" << std::endl; 
        break;
        }

    int nError = WSAGetLastError(); 
    if (nError != WSAEWOULDBLOCK)
        {
        std::cout << "Winsock error code: " << nError << std::endl; 
        break;
        }

    // optionally call select() here to wait for the socket
    // to receive data before calling recv() again...
    /*
    fd_set fd;
    FD_ZERO(&fd);
    FD_SET(Socket, &fd);

    timeval tv;
    tv.tv_sec = ...;
    tv.tv_usec = ...;

    nError = select(Socket+1, &fd, NULL, NULL, &tv);
    if (nError == 0)
        {
        std::cout << "Timeout waiting for data" << std::endl; 
        break;
        }

    if (nError == SOCKET_ERROR)
        {
        nError = WSAGetLastError();
        std::cout << "Winsock error code: " << nError << std::endl; 
        break;
        }
    */
    } 
while (true);

// Shutdown our socket 
shutdown(Socket, SD_SEND); 

// Close our socket entirely 
closesocket(Socket); 

The loop is not checking for errors correctly. It needs to be more like this instead:

char buffer[1000]; 
int inDataLength;

do 
    {
    inDataLength = recv(Socket, buffer, sizeof(buffer), 0); 
    if (inDataLength > 0)
        {
        // inDataLength number of bytes were received, use buffer as needed...
        continue;
        }

    if (inDataLength == 0)
        {
        std::cout << "Client disconnected!" << std::endl; 
        break;
        }

    int nError = WSAGetLastError(); 
    if (nError != WSAEWOULDBLOCK)
        {
        std::cout << "Winsock error code: " << nError << std::endl; 
        break;
        }

    // optionally call select() here to wait for the socket
    // to receive data before calling recv() again...
    /*
    fd_set fd;
    FD_ZERO(&fd);
    FD_SET(Socket, &fd);

    timeval tv;
    tv.tv_sec = ...;
    tv.tv_usec = ...;

    nError = select(Socket+1, &fd, NULL, NULL, &tv);
    if (nError == 0)
        {
        std::cout << "Timeout waiting for data" << std::endl; 
        break;
        }

    if (nError == SOCKET_ERROR)
        {
        nError = WSAGetLastError();
        std::cout << "Winsock error code: " << nError << std::endl; 
        break;
        }
    */
    } 
while (true);

// Shutdown our socket 
shutdown(Socket, SD_SEND); 

// Close our socket entirely 
closesocket(Socket); 
扶醉桌前 2024-10-09 08:14:36
if((nError == SOCKET_ERROR) || (nError == 0))
    WSAGetLastError();
else
    ; // handle success

这就是它应该看起来的样子,而不是你是如何做到的。

if((nError == SOCKET_ERROR) || (nError == 0))
    WSAGetLastError();
else
    ; // handle success

That's how it should look, and not how you did it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文