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; }
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; }
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; }