qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 len,
                                                   const QHostAddress &address, quint16 port)
{
    qint64 ret = -1;
    struct sockaddr_in sockAddrIPv4;
    qt_sockaddr_in6 sockAddrIPv6;
    struct sockaddr *sockAddrPtr;
    QT_SOCKLEN_T sockAddrSize;

    qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);

    if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based && len > qint64(qt_socket_getMaxMsgSize(socketDescriptor))) {
        // WSAEMSGSIZE is not reliable enough (win 9x) so we check max size our self.
        setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString);
    } else {
        WSABUF buf;
#if !defined(Q_OS_WINCE)
        buf.buf = len ? (char*)data : 0;
#else
        char tmp;
        buf.buf = len ? (char*)data : &tmp;
#endif
        buf.len = len;
        DWORD flags = 0;
        DWORD bytesSent = 0;
        if (::WSASendTo(socketDescriptor, &buf, 1, &bytesSent, flags, sockAddrPtr, sockAddrSize, 0,0) ==  SOCKET_ERROR) {
            int err = WSAGetLastError();
            WS_ERROR_DEBUG(err);
            switch (err) {
            case WSAEMSGSIZE:
                setError(QAbstractSocket::DatagramTooLargeError, DatagramTooLargeErrorString);
                break;
            default:
                setError(QAbstractSocket::NetworkError, SendDatagramErrorString);
                break;
            }
            ret = -1;
        } else {
            ret = qint64(bytesSent);
        }
    }
#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %li, \"%s\", %i) == %li", data,
           qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), 0, address.toString().toLatin1().constData(),
           port, ret);
#endif

    return ret;
}
예제 #2
0
bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 port)
{
    struct sockaddr_in sockAddrIPv4;
    qt_sockaddr_in6 sockAddrIPv6;
    struct sockaddr *sockAddrPtr = 0;
    QT_SOCKLEN_T sockAddrSize = 0;

    qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);


    int bindResult = ::bind(socketDescriptor, sockAddrPtr, sockAddrSize);
    if (bindResult == SOCKET_ERROR) {
        int err = WSAGetLastError();
        WS_ERROR_DEBUG(err);
        switch (err) {
        case WSANOTINITIALISED:
            //###
            break;
        case WSAEADDRINUSE:
        case WSAEINVAL:
            setError(QAbstractSocket::AddressInUseError, AddressInuseErrorString);
            break;
        case WSAEACCES:
            setError(QAbstractSocket::SocketAccessError, AddressProtectedErrorString);
            break;
        case WSAEADDRNOTAVAIL:
            setError(QAbstractSocket::SocketAddressNotAvailableError, AddressNotAvailableErrorString);
            break;
        default:
            break;
        }

#if defined (QNATIVESOCKETENGINE_DEBUG)
        qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)",
               address.toString().toLatin1().constData(), port, socketErrorString.toLatin1().constData());
#endif

        return false;
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true",
           address.toString().toLatin1().constData(), port);
#endif
    socketState = QAbstractSocket::BoundState;
    return true;
}
예제 #3
0
bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quint16 port)
{

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeConnect() to %s :: %i", address.toString().toLatin1().constData(), port);
#endif

    struct sockaddr_in sockAddrIPv4;
    qt_sockaddr_in6 sockAddrIPv6;
    struct sockaddr *sockAddrPtr = 0;
    QT_SOCKLEN_T sockAddrSize = 0;

    qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);

    forever {
        int connectResult = ::WSAConnect(socketDescriptor, sockAddrPtr, sockAddrSize, 0,0,0,0);
        if (connectResult == SOCKET_ERROR) {
            int err = WSAGetLastError();
            WS_ERROR_DEBUG(err);

            switch (err) {
            case WSANOTINITIALISED:
                //###
                break;
            case WSAEISCONN:
                socketState = QAbstractSocket::ConnectedState;
                break;
            case WSAEWOULDBLOCK: {
                // If WSAConnect returns WSAEWOULDBLOCK on the second
                // connection attempt, we have to check SO_ERROR's
                // value to detect ECONNREFUSED. If we don't get
                // ECONNREFUSED, we'll have to treat it as an
                // unfinished operation.
                int value = 0;
                QT_SOCKLEN_T valueSize = sizeof(value);
                if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
                    if (value == WSAECONNREFUSED) {
                        setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
                        socketState = QAbstractSocket::UnconnectedState;
                        break;
                    }
                    if (value == WSAETIMEDOUT) {
                        setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
                        socketState = QAbstractSocket::UnconnectedState;
                        break;
                    }
                    if (value == WSAEHOSTUNREACH) {
                        setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
                        socketState = QAbstractSocket::UnconnectedState;
                        break;
                    }
                    if (value == WSAEADDRNOTAVAIL) {
                        setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString);
                        socketState = QAbstractSocket::UnconnectedState;
                        break;
                    }
                }
                // fall through
            }
            case WSAEINPROGRESS:
                setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString);
                socketState = QAbstractSocket::ConnectingState;
                break;
            case WSAEADDRINUSE:
                setError(QAbstractSocket::NetworkError, AddressInuseErrorString);
                break;
            case WSAECONNREFUSED:
                setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
                socketState = QAbstractSocket::UnconnectedState;
                break;
            case WSAETIMEDOUT:
                setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
                break;
            case WSAEACCES:
                setError(QAbstractSocket::SocketAccessError, AccessErrorString);
                socketState = QAbstractSocket::UnconnectedState;
                break;
            case WSAEHOSTUNREACH:
                setError(QAbstractSocket::NetworkError, HostUnreachableErrorString);
                socketState = QAbstractSocket::UnconnectedState;
                break;
            case WSAENETUNREACH:
                setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString);
                socketState = QAbstractSocket::UnconnectedState;
                break;
            case WSAEINVAL:
            case WSAEALREADY:
                setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString);
                break;
            default:
                break;
            }
            if (socketState != QAbstractSocket::ConnectedState) {
#if defined (QNATIVESOCKETENGINE_DEBUG)
                qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)",
                        address.toString().toLatin1().constData(), port,
                        socketState == QAbstractSocket::ConnectingState
                        ? "Connection in progress" : socketErrorString.toLatin1().constData());
#endif
                return false;
            }
        }
        break;
    }

#if defined (QNATIVESOCKETENGINE_DEBUG)
    qDebug("QNativeSocketEnginePrivate::nativeConnect(%s, %i) == true",
           address.toString().toLatin1().constData(), port);
#endif

    socketState = QAbstractSocket::ConnectedState;
    return true;
}