当前位置: 首页 > 知识库问答 >
问题:

recv()在非阻塞tcp ip套接字的对等端断开时返回-1

师谦
2023-03-14

我正在使用TCP/IP套接字,我已经读过recv函数。因此,每当对等体断开连接时,recv按照文档返回0,但在windows上它不返回零,而是返回-1,并且errono中的值是0我无法理解它为什么这样做。同样的代码在Linux中运行得非常好。

// some headers i used
#ifdef _WIN32
/* See http://stackoverflow.com/questions/12765743/getaddrinfo-on-win32 */
#    ifndef _WIN32_WINNT
#        define _WIN32_WINNT 0x0501 /* Windows XP. */
#    endif
#    include <Ws2tcpip.h>
#    include <winsock2.h>

#    ifdef _MSC_VER
#        pragma comment(lib, "Ws2_32.lib")
#    endif

#    define SHUT_RDWR SD_BOTH
#else
/* Assume that any non-Windows platform uses POSIX-style sockets instead. */
#    include <arpa/inet.h>
#    include <fcntl.h>
#    include <netinet/in.h>
#    include <netinet/tcp.h>
#    include <sys/socket.h>
#    include <unistd.h>

#    define NO_ERROR 0
#    define INVALID_SOCKET -1
#    define SOCKET_ERROR -1
#endif

// MSG_DONTWAIT is not available on some platforms, if it doesn't exist define it as 0
#if !defined(MSG_DONTWAIT)
#    define MSG_DONTWAIT 0
#endif
//

std::vector<std::string> Peer::read(const int length)
{
    static std::vector<char> tempRecvBuf(2 * 1000000);
    tempRecvBuf.clear();
    int recv = ::recv(m_socket.resource(), &tempRecvBuf[0], length, MSG_DONTWAIT);

    if (recv == SOCKET_ERROR ) {
        if (errno == WSAECONNRESET) {
            return {};
        }
        else {
            return {};
    }

    if (recv == 0) {
        // Connection is no longer valid, remote has been disconnected
        m_connected = false;
        this->m_master->events()->onPeerDisconnect()->trigger(this);
        this->m_master->peers()->remove(this);
        return {};
    }

共有1个答案

孙玺
2023-03-14

根据Microsoft Windows套接字文档的这一页,函数recv将在正常关闭时返回0;在错误(包括中止关闭)时返回socket_error(可能定义为-1)。如文档中所述,您必须调用WSAGETLastError来获取错误代码。它不存储errno中。

 类似资料:
  • 另外,除了调用recv函数后检查WSAGetLastError的值之外,是否还有其他方法可以使用TCP套接字库检测网络断开? 多谢!

  • 问题内容: 为什么有人会喜欢阻止写而不是非阻止写?我的理解是,仅当您想确保写方法返回后,另一端获得了TCP数据包时,才希望阻止写操作,但是我什至不知道这是可能的。您将必须刷新,而刷新则必须刷新 底层操作系统的写套接字缓冲区 。那么,无阻塞套接字写是否有任何缺点?就性能而言,拥有较大的底层写套接字是否会缓冲一个不好的主意?我的理解是,底层套接字写缓冲区越小,当底层套接字缓冲区已满且isWritabl

  • 问题内容: 我想创建一个非阻塞连接。像这样: 为此,我使用了另一个线程,无限循环和Linux epoll。像这样(伪代码): 如果我先运行服务器,然后运行客户端,那么一切正常。如果我先运行客户端,请稍等一会儿,再运行服务器,然后客户端将无法连接。 我究竟做错了什么?也许可以做不同的事情? 问题答案: 您应该使用以下步骤进行异步连接: 用创建套接字 开始与 如果返回值既不是也不是,则中止并返回错误

  • 问题内容: 就像标题所说的那样,我需要一种方法来停止或中断正在等待套接字输入的阻塞线程。 问题答案: Thread.interrupt()应该是您要寻找的方法。确保您的输入访问方法也检查InterruptedException和ClosedByInterruptException。 另请参阅Sun Concurrency Tutorial 中的相应页面,作为另一种解决方案的建议。

  • 下面的代码允许服务器等待客户端连接到(已经绑定的)套接字。它在客户端连接到套接字时终止,或者在“server_run”取值0时终止:这允许代码的其他部分在合适的时候关闭服务器。 根据对另一个帖子(C:non blocking sockets with timeout:how to check if connection request was made?)的回答和评论,这不是一种方法,因为它涉及到

  • 我正在实现一个UNIX域套接字进程间通信代码,在试图从套接字读取时,我随机地碰到了这个错误--“errno 11:资源暂时不可用”。我使用MSG_PEEK从套接字读取字节数,并为接收缓冲区分配字节数,并读取实际数据。 套接字是一个阻塞套接字,我没有任何非阻塞的代码(总之,接受/读/写)。在阻塞套接字读取中,有什么可能导致这种情况的指针吗?在MSG_PEEK的手册页中,当socket标记为非阻塞时,