pocoライブラリstreamsocket送信データ失敗エラーコード取得

7587 ワード

sendBytesを使用してデータを送信し、関数は次のように実現されます.
int StreamSocket::sendBytes(const void* buffer, int length, int flags)
{
    return impl()->sendBytes(buffer, length, flags);
}


int StreamSocket::sendBytes(FIFOBuffer& fifoBuf)
{
    ScopedLock l(fifoBuf.mutex());

    int ret = impl()->sendBytes(fifoBuf.begin(), (int) fifoBuf.used());
    if (ret > 0) fifoBuf.drain(ret);
    return ret;
}

今socketimplのsendBytesを見てみましょう
int SocketImpl::sendBytes(const void* buffer, int length, int flags)
{
    if (_isBrokenTimeout)
    {
        if (_sndTimeout.totalMicroseconds() != 0)
        {
            if (!poll(_sndTimeout, SELECT_WRITE))
                throw TimeoutException();
        }
    }

    int rc;
    do
    {
        if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException();
        rc = ::send(_sockfd, reinterpret_cast(buffer), length, flags);
    }
    while (_blocking && rc < 0 && lastError() == POCO_EINTR);
    if (rc < 0) error();
    return rc;
}

最終的にはrcを返しただけで、送信内容の長さは0未満ですが、error()はerror関数を見てください.
void SocketImpl::error()
{
    int err = lastError();
    std::string empty;
    error(err, empty);
}

ここで呼び出されたlastError関数は、windowから取得されたエラーコードであることがわかります.
inline int SocketImpl::lastError()
{
#if defined(_WIN32)
    return WSAGetLastError();
#else
    return errno;
#endif
}

最後の処理関数は次のとおりです.
void SocketImpl::error(int code, const std::string& arg)
{
    switch (code)
    {
    case POCO_ENOERR: return;
    case POCO_ESYSNOTREADY:
        throw NetException("Net subsystem not ready", code);
    case POCO_ENOTINIT:
        throw NetException("Net subsystem not initialized", code);
    case POCO_EINTR:
        throw IOException("Interrupted", code);
    case POCO_EACCES:
        throw IOException("Permission denied", code);
    case POCO_EFAULT:
        throw IOException("Bad address", code);
    case POCO_EINVAL:
        throw InvalidArgumentException(code);
    case POCO_EMFILE:
        throw IOException("Too many open files", code);
    case POCO_EWOULDBLOCK:
        throw IOException("Operation would block", code);
    case POCO_EINPROGRESS:
        throw IOException("Operation now in progress", code);
    case POCO_EALREADY:
        throw IOException("Operation already in progress", code);
    case POCO_ENOTSOCK:
        throw IOException("Socket operation attempted on non-socket", code);
    case POCO_EDESTADDRREQ:
        throw NetException("Destination address required", code);
    case POCO_EMSGSIZE:
        throw NetException("Message too long", code);
    case POCO_EPROTOTYPE:
        throw NetException("Wrong protocol type", code);
    case POCO_ENOPROTOOPT:
        throw NetException("Protocol not available", code);
    case POCO_EPROTONOSUPPORT:
        throw NetException("Protocol not supported", code);
    case POCO_ESOCKTNOSUPPORT:
        throw NetException("Socket type not supported", code);
    case POCO_ENOTSUP:
        throw NetException("Operation not supported", code);
    case POCO_EPFNOSUPPORT:
        throw NetException("Protocol family not supported", code);
    case POCO_EAFNOSUPPORT:
        throw NetException("Address family not supported", code);
    case POCO_EADDRINUSE:
        throw NetException("Address already in use", arg, code);
    case POCO_EADDRNOTAVAIL:
        throw NetException("Cannot assign requested address", arg, code);
    case POCO_ENETDOWN:
        throw NetException("Network is down", code);
    case POCO_ENETUNREACH:
        throw NetException("Network is unreachable", code);
    case POCO_ENETRESET:
        throw NetException("Network dropped connection on reset", code);
    case POCO_ECONNABORTED:
        throw ConnectionAbortedException(code);
    case POCO_ECONNRESET:
        throw ConnectionResetException(code);
    case POCO_ENOBUFS:
        throw IOException("No buffer space available", code);
    case POCO_EISCONN:
        throw NetException("Socket is already connected", code);
    case POCO_ENOTCONN:
        throw NetException("Socket is not connected", code);
    case POCO_ESHUTDOWN:
        throw NetException("Cannot send after socket shutdown", code);
    case POCO_ETIMEDOUT:
        throw TimeoutException(code);
    case POCO_ECONNREFUSED:
        throw ConnectionRefusedException(arg, code);
    case POCO_EHOSTDOWN:
        throw NetException("Host is down", arg, code);
    case POCO_EHOSTUNREACH:
        throw NetException("No route to host", arg, code);
#if defined(POCO_OS_FAMILY_UNIX)
    case EPIPE:
        throw IOException("Broken pipe", code);
    case EBADF:
        throw IOException("Bad socket descriptor", code);
    case ENOENT:
        throw IOException("Not found", arg, code);
#endif
    default:
        throw IOException(NumberFormatter::format(code), arg, code);
    }
}

異常も投げ出していることがわかるので異常をキャプチャしてエラーコードとメッセージを印刷するとエラーコードが見つかりますPOCO_ENOCONN、これらのマクロはsocketDefs.hに定義され、内容は以下の通りです.
#include "Poco/UnWindows.h"
    #include 
    #include 
    #define POCO_INVALID_SOCKET  INVALID_SOCKET
    #define poco_socket_t        SOCKET
    #define poco_socklen_t       int
    #define poco_ioctl_request_t int
    #define poco_closesocket(s)  closesocket(s)
    #define POCO_EINTR           WSAEINTR
    #define POCO_EACCES          WSAEACCES
    #define POCO_EFAULT          WSAEFAULT
    #define POCO_EINVAL          WSAEINVAL
    #define POCO_EMFILE          WSAEMFILE
    #define POCO_EAGAIN          WSAEWOULDBLOCK
    #define POCO_EWOULDBLOCK     WSAEWOULDBLOCK
    #define POCO_EINPROGRESS     WSAEINPROGRESS
    #define POCO_EALREADY        WSAEALREADY
    #define POCO_ENOTSOCK        WSAENOTSOCK
    #define POCO_EDESTADDRREQ    WSAEDESTADDRREQ
    #define POCO_EMSGSIZE        WSAEMSGSIZE
    #define POCO_EPROTOTYPE      WSAEPROTOTYPE
    #define POCO_ENOPROTOOPT     WSAENOPROTOOPT
    #define POCO_EPROTONOSUPPORT WSAEPROTONOSUPPORT
    #define POCO_ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
    #define POCO_ENOTSUP         WSAEOPNOTSUPP
    #define POCO_EPFNOSUPPORT    WSAEPFNOSUPPORT
    #define POCO_EAFNOSUPPORT    WSAEAFNOSUPPORT
    #define POCO_EADDRINUSE      WSAEADDRINUSE
    #define POCO_EADDRNOTAVAIL   WSAEADDRNOTAVAIL
    #define POCO_ENETDOWN        WSAENETDOWN
    #define POCO_ENETUNREACH     WSAENETUNREACH
    #define POCO_ENETRESET       WSAENETRESET
    #define POCO_ECONNABORTED    WSAECONNABORTED
    #define POCO_ECONNRESET      WSAECONNRESET
    #define POCO_ENOBUFS         WSAENOBUFS
    #define POCO_EISCONN         WSAEISCONN
    #define POCO_ENOTCONN        WSAENOTCONN
    #define POCO_ESHUTDOWN       WSAESHUTDOWN
    #define POCO_ETIMEDOUT       WSAETIMEDOUT
    #define POCO_ECONNREFUSED    WSAECONNREFUSED
    #define POCO_EHOSTDOWN       WSAEHOSTDOWN
    #define POCO_EHOSTUNREACH    WSAEHOSTUNREACH
    #define POCO_ESYSNOTREADY    WSASYSNOTREADY
    #define POCO_ENOTINIT        WSANOTINITIALISED
    #define POCO_HOST_NOT_FOUND  WSAHOST_NOT_FOUND
    #define POCO_TRY_AGAIN       WSATRY_AGAIN
    #define POCO_NO_RECOVERY     WSANO_RECOVERY
    #define POCO_NO_DATA         WSANO_DATA

これは明らかでしょうwindows標準のエラーコード