summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qnativesocketengine_win.cpp
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-07-24 09:45:33 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-07-27 13:04:30 (GMT)
commit3643028959f0b38350e57e60ba4000435b75e592 (patch)
treec129e4dee11487abd437ab8ebd993ba261e06fa6 /src/network/socket/qnativesocketengine_win.cpp
parentcf66c667a97c0079141eb3f2d9e997b7378ae792 (diff)
parentc36139c665e61866aff4bf8572890a735167a7d0 (diff)
downloadQt-3643028959f0b38350e57e60ba4000435b75e592.zip
Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.gz
Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.bz2
Merge commit 'qt/master-stable'
Conflicts: configure.exe qmake/Makefile.unix qmake/generators/makefile.cpp src/corelib/global/qglobal.h src/corelib/kernel/kernel.pri src/corelib/kernel/qcoreevent.cpp src/corelib/kernel/qsharedmemory_unix.cpp src/gui/graphicsview/qgraphicsscene.cpp src/gui/kernel/qaction.cpp src/gui/kernel/qaction.h src/gui/kernel/qaction_p.h src/gui/kernel/qapplication.cpp src/gui/kernel/qapplication.h src/gui/kernel/qwidget.cpp src/gui/kernel/qwidget.h src/gui/kernel/qwidget_mac.mm src/gui/painting/qgraphicssystemfactory.cpp src/gui/styles/qwindowsstyle.cpp src/gui/text/qfontengine_qpf.cpp src/gui/widgets/qabstractscrollarea_p.h src/network/access/qnetworkaccessdebugpipebackend.cpp src/network/socket/qlocalsocket_unix.cpp src/network/socket/qnativesocketengine_p.h src/network/socket/qnativesocketengine_unix.cpp src/openvg/qpaintengine_vg.cpp tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp tests/auto/qcssparser/qcssparser.pro tests/auto/qdir/tst_qdir.cpp tests/auto/qfile/tst_qfile.cpp tests/auto/qobject/tst_qobject.cpp tests/auto/qpathclipper/qpathclipper.pro tests/auto/qprocess/tst_qprocess.cpp tests/auto/qsettings/tst_qsettings.cpp tests/auto/qsharedpointer/qsharedpointer.pro tests/auto/qsqlquerymodel/qsqlquerymodel.pro tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro tests/auto/qsqltablemodel/qsqltablemodel.pro tests/auto/qsqlthread/qsqlthread.pro tests/auto/qwidget/tst_qwidget.cpp
Diffstat (limited to 'src/network/socket/qnativesocketengine_win.cpp')
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp153
1 files changed, 71 insertions, 82 deletions
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 59a3b60..f0b9f0b 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -166,11 +166,11 @@ static QByteArray qt_prettyDebug(const char *data, int len, int maxLength)
Extracts the port and address from a sockaddr, and stores them in
\a port and \a addr if they are non-null.
*/
-static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, struct sockaddr *sa, quint16 *port, QHostAddress *address)
+static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt_sockaddr *sa, quint16 *port, QHostAddress *address)
{
#if !defined (QT_NO_IPV6)
- if (sa->sa_family == AF_INET6) {
- qt_sockaddr_in6 *sa6 = (qt_sockaddr_in6 *)sa;
+ if (sa->a.sa_family == AF_INET6) {
+ const qt_sockaddr_in6 *sa6 = &sa->a6;
Q_IPV6ADDR tmp;
for (int i = 0; i < 16; ++i)
tmp.c[i] = sa6->sin6_addr.qt_s6_addr[i];
@@ -182,8 +182,8 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, struct s
WSANtohs(socketDescriptor, sa6->sin6_port, port);
} else
#endif
- if (sa->sa_family == AF_INET) {
- struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
+ if (sa->a.sa_family == AF_INET) {
+ const sockaddr_in *sa4 = &sa->a4;
unsigned long addr;
WSANtohl(socketDescriptor, sa4->sin_addr.s_addr, &addr);
QHostAddress a;
@@ -362,6 +362,8 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
return -1;
int n = -1;
+ int level = SOL_SOCKET; // default
+
switch (opt) {
case QNativeSocketEngine::ReceiveBufferSocketOption:
n = SO_RCVBUF;
@@ -389,11 +391,18 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co
case QNativeSocketEngine::ReceiveOutOfBandData:
n = SO_OOBINLINE;
break;
+ case QNativeSocketEngine::LowDelayOption:
+ level = IPPROTO_TCP;
+ n = TCP_NODELAY;
+ break;
+ case QNativeSocketEngine::KeepAliveOption:
+ n = SO_KEEPALIVE;
+ break;
}
int v = -1;
QT_SOCKOPTLEN_T len = sizeof(v);
- if (getsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, &len) != -1)
+ if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1)
return v;
return -1;
}
@@ -409,6 +418,8 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
return false;
int n = 0;
+ int level = SOL_SOCKET; // default
+
switch (opt) {
case QNativeSocketEngine::ReceiveBufferSocketOption:
n = SO_RCVBUF;
@@ -440,9 +451,16 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
case QNativeSocketEngine::ReceiveOutOfBandData:
n = SO_OOBINLINE;
break;
+ case QNativeSocketEngine::LowDelayOption:
+ level = IPPROTO_TCP;
+ n = TCP_NODELAY;
+ break;
+ case QNativeSocketEngine::KeepAliveOption:
+ n = SO_KEEPALIVE;
+ break;
}
- if (::setsockopt(socketDescriptor, SOL_SOCKET, n, (char*)&v, sizeof(v)) != 0) {
+ if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) {
WS_ERROR_DEBUG(WSAGetLastError());
return false;
}
@@ -463,20 +481,15 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
if (socketDescriptor == -1)
return false;
-#if !defined (QT_NO_IPV6)
- struct qt_sockaddr_storage sa;
-#else
- struct sockaddr_in sa;
-#endif
- struct sockaddr *pSa = (struct sockaddr *) &sa;
-
- QT_SOCKLEN_T sz = sizeof(sa);
+ qt_sockaddr sa;
+ QT_SOCKLEN_T sockAddrSize = sizeof(sa);
+ // Determine local address
memset(&sa, 0, sizeof(sa));
- if (::getsockname(socketDescriptor, pSa, &sz) == 0) {
- qt_socket_getPortAndAddress(socketDescriptor, pSa, &localPort, &localAddress);
+ if (::getsockname(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
+ qt_socket_getPortAndAddress(socketDescriptor, &sa, &localPort, &localAddress);
// Determine protocol family
- switch (pSa->sa_family) {
+ switch (sa.a.sa_family) {
case AF_INET:
socketProtocol = QAbstractSocket::IPv4Protocol;
break;
@@ -500,8 +513,8 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
}
memset(&sa, 0, sizeof(sa));
- if (::getpeername(socketDescriptor, pSa, &sz) == 0) {
- qt_socket_getPortAndAddress(socketDescriptor, pSa, &peerPort, &peerAddress);
+ if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
+ qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress);
} else {
WS_ERROR_DEBUG(WSAGetLastError());
}
@@ -533,8 +546,8 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
struct sockaddr_in sockAddrIPv4;
qt_sockaddr_in6 sockAddrIPv6;
- struct sockaddr *sockAddrPtr;
- QT_SOCKLEN_T sockAddrSize;
+ struct sockaddr *sockAddrPtr = 0;
+ QT_SOCKLEN_T sockAddrSize = 0;
qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);
@@ -638,8 +651,8 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16
{
struct sockaddr_in sockAddrIPv4;
qt_sockaddr_in6 sockAddrIPv6;
- struct sockaddr *sockAddrPtr;
- QT_SOCKLEN_T sockAddrSize;
+ struct sockaddr *sockAddrPtr = 0;
+ QT_SOCKLEN_T sockAddrSize = 0;
qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);
@@ -766,20 +779,9 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const
{
#if !defined(Q_OS_WINCE)
// Create a sockaddr struct and reset its port number.
-#if !defined(QT_NO_IPV6)
- qt_sockaddr_in6 storage;
- qt_sockaddr_in6 *storagePtrIPv6 = reinterpret_cast<qt_sockaddr_in6 *>(&storage);
- storagePtrIPv6->sin6_port = 0;
-#else
- struct sockaddr storage;
-#endif
- sockaddr *storagePtr = reinterpret_cast<sockaddr *>(&storage);
- storagePtr->sa_family = 0;
-
- sockaddr_in *storagePtrIPv4 = reinterpret_cast<sockaddr_in *>(&storage);
- storagePtrIPv4->sin_port = 0;
+ qt_sockaddr storage;
QT_SOCKLEN_T storageSize = sizeof(storage);
-
+ memset(&storage, 0, storageSize);
bool result = false;
@@ -791,7 +793,7 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const
buf.len = sizeof(c);
DWORD available = 0;
DWORD flags = MSG_PEEK;
- int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, storagePtr, &storageSize,0,0);
+ int ret = ::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags, &storage.a, &storageSize,0,0);
int err = WSAGetLastError();
if (ret == SOCKET_ERROR && err != WSAEMSGSIZE) {
WS_ERROR_DEBUG(err);
@@ -801,7 +803,7 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const
// notifiers.
flags = 0;
::WSARecvFrom(socketDescriptor, &buf, 1, &available, &flags,
- storagePtr, &storageSize, 0, 0);
+ &storage.a, &storageSize, 0, 0);
}
} else {
// If there's no error, or if our buffer was too small, there must be
@@ -893,14 +895,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
{
qint64 ret = 0;
-#if !defined(QT_NO_IPV6)
- qt_sockaddr_storage aa;
-#else
- struct sockaddr_in aa;
-#endif
+ qt_sockaddr aa;
memset(&aa, 0, sizeof(aa));
QT_SOCKLEN_T sz;
sz = sizeof(aa);
+
WSABUF buf;
buf.buf = data;
buf.len = maxLength;
@@ -915,23 +914,17 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
DWORD flags = 0;
DWORD bytesRead = 0;
- int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, (struct sockaddr *) &aa, &sz,0,0);
+ int wsaRet = ::WSARecvFrom(socketDescriptor, &buf, 1, &bytesRead, &flags, &aa.a, &sz,0,0);
if (wsaRet == SOCKET_ERROR) {
int err = WSAGetLastError();
- if (err == WSAEMSGSIZE) {
- // it is ok the buffer was to small if bytesRead is larger than
- // maxLength (win 9x) then assume bytes read is really maxLenth
- ret = qint64(bytesRead) > maxLength ? maxLength : qint64(bytesRead);
- } else {
- WS_ERROR_DEBUG(err);
- setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);
- ret = -1;
- }
+ WS_ERROR_DEBUG(err);
+ setError(QAbstractSocket::NetworkError, ReceiveDatagramErrorString);
+ ret = -1;
} else {
ret = qint64(bytesRead);
}
- qt_socket_getPortAndAddress(socketDescriptor, (struct sockaddr *) &aa, port, address);
+ qt_socket_getPortAndAddress(socketDescriptor, &aa, port, address);
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %li, %s, %i) == %li",
@@ -950,41 +943,37 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
qint64 ret = -1;
struct sockaddr_in sockAddrIPv4;
qt_sockaddr_in6 sockAddrIPv6;
- struct sockaddr *sockAddrPtr;
- QT_SOCKLEN_T sockAddrSize;
+ struct sockaddr *sockAddrPtr = 0;
+ QT_SOCKLEN_T sockAddrSize = 0;
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;
+ WSABUF buf;
#if !defined(Q_OS_WINCE)
- buf.buf = len ? (char*)data : 0;
+ buf.buf = len ? (char*)data : 0;
#else
- char tmp;
- buf.buf = len ? (char*)data : &tmp;
+ 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);
+ 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(),