diff options
author | Benoit Foucher <benoit@zeroc.com> | 2007-05-23 12:49:48 +0000 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2007-05-23 12:49:48 +0000 |
commit | 4f11b3b9bc858d7a5a8741fcb06ca61ce8189d6c (patch) | |
tree | 3fa912fd7db2b611fb76a8f7bc9547c39737b024 /cpp/src/Ice/Network.cpp | |
parent | Fixed VS8 compilation error (diff) | |
download | ice-4f11b3b9bc858d7a5a8741fcb06ca61ce8189d6c.tar.bz2 ice-4f11b3b9bc858d7a5a8741fcb06ca61ce8189d6c.tar.xz ice-4f11b3b9bc858d7a5a8741fcb06ca61ce8189d6c.zip |
Added Ice.TCP.SndSize/Ice.TCP.RcvSize properties, fixed throughput issue on
Win32.
Diffstat (limited to 'cpp/src/Ice/Network.cpp')
-rw-r--r-- | cpp/src/Ice/Network.cpp | 197 |
1 files changed, 95 insertions, 102 deletions
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 6e907c4bdbe..8e02559e8c6 100644 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -10,6 +10,8 @@ #include <IceUtil/StaticMutex.h> #include <Ice/Network.h> #include <Ice/LocalException.h> +#include <Ice/Properties.h> // For setTcpBufSize +#include <Ice/LoggerUtil.h> // For setTcpBufSize #if defined(_WIN32) # include <winsock2.h> @@ -1297,10 +1299,66 @@ IceInternal::getLocalHosts() vector<string> result; #if defined(_WIN32) - vector<struct sockaddr_in> addrs = getLocalAddresses(); - for(unsigned int i = 0; i < addrs.size(); ++i) + try { - result.push_back(inetAddrToString(addrs[i].sin_addr)); + SOCKET fd = createSocket(false); + + vector<unsigned char> buffer; + buffer.resize(1024); + unsigned long len = 0; + DWORD rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, + &buffer[0], static_cast<DWORD>(buffer.size()), + &len, 0, 0); + if(rs == SOCKET_ERROR) + { + // + // If the buffer wasn't big enough, resize it to the + // required length and try again. + // + if(getSocketErrno() == WSAEFAULT) + { + buffer.resize(len); + rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, + &buffer[0], static_cast<DWORD>(buffer.size()), + &len, 0, 0); + } + + if(rs == SOCKET_ERROR) + { + closeSocketNoThrow(fd); + SocketException ex(__FILE__, __LINE__); + ex.error = getSocketErrno(); + throw ex; + } + } + + // + // Add the local interface addresses. + // + SOCKET_ADDRESS_LIST* addrs = reinterpret_cast<SOCKET_ADDRESS_LIST*>(&buffer[0]); + for (int i = 0; i < addrs->iAddressCount; ++i) + { + result.push_back( + inetAddrToString(reinterpret_cast<struct sockaddr_in*>(addrs->Address[i].lpSockaddr)->sin_addr)); + } + + // + // Add the loopback interface address. + // + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(0); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + result.push_back(inetAddrToString(addr.sin_addr)); + + closeSocket(fd); + } + catch(const Ice::LocalException&) + { + // + // TODO: Warning? + // } #elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__) struct ifaddrs* ifap; @@ -1397,118 +1455,53 @@ IceInternal::getLocalHosts() return result; } -#ifdef _WIN32 -vector<struct sockaddr_in> -IceInternal::getLocalAddresses() +void +IceInternal::setTcpBufSize(SOCKET fd, const Ice::PropertiesPtr& properties, const Ice::LoggerPtr& logger) { - vector<struct sockaddr_in> result; - try - { - SOCKET fd = createSocket(false); - - vector<unsigned char> buffer; - buffer.resize(1024); - unsigned long len = 0; - DWORD rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, - &buffer[0], static_cast<DWORD>(buffer.size()), - &len, 0, 0); - if(rs == SOCKET_ERROR) - { - // - // If the buffer wasn't big enough, resize it to the - // required length and try again. - // - if(getSocketErrno() == WSAEFAULT) - { - buffer.resize(len); - rs = WSAIoctl(fd, SIO_ADDRESS_LIST_QUERY, 0, 0, - &buffer[0], static_cast<DWORD>(buffer.size()), - &len, 0, 0); - } + assert(fd != INVALID_SOCKET); - if(rs == SOCKET_ERROR) - { - closeSocketNoThrow(fd); - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - } - // - // Add the local interface addresses. - // - SOCKET_ADDRESS_LIST* addrs = reinterpret_cast<SOCKET_ADDRESS_LIST*>(&buffer[0]); - for (int i = 0; i < addrs->iAddressCount; ++i) - { - result.push_back(*reinterpret_cast<struct sockaddr_in*>(addrs->Address[i].lpSockaddr)); - } - - // - // Add the loopback interface address. - // - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(0); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - result.push_back(addr); + // + // By default, on Windows we use a 128KB buffer size. On Unix + // platforms, we use the system defaults. + // +#ifdef _WIN32 + const int dfltBufSize = 128 * 1024; +#else + const int dfltBufSize = 0; +#endif + Int sizeRequested; - closeSocket(fd); - } - catch(const Ice::LocalException&) + sizeRequested = properties->getPropertyAsIntWithDefault("Ice.TCP.RcvSize", dfltBufSize); + if(sizeRequested > 0) { // - // TODO: Warning? + // Try to set the buffer size. The kernel will silently adjust + // the size to an acceptable value. Then read the size back to + // get the size that was actually set. // - } - return result; -} - -bool -IceInternal::isLocalAddress(const struct sockaddr_in& addr) -{ - struct sockaddr_in addr0 = addr; - addr0.sin_port = htons(0); // Local interface addresses have the port set to 0. - - try - { - vector<struct sockaddr_in> localAddrs = getLocalAddresses(); - for(vector<struct sockaddr_in>::const_iterator p = localAddrs.begin(); p != localAddrs.end(); ++p) + setRecvBufferSize(fd, sizeRequested); + int size = getRecvBufferSize(fd); + if(size < sizeRequested) // Warn if the size that was set is less than the requested size. { - if(compareAddress(addr0, *p)) - { - return true; - } + Ice::Warning out(logger); + out << "TCP receive buffer size: requested size of " << sizeRequested << " adjusted to " << size; } } - catch(const Ice::LocalException&) + + sizeRequested = properties->getPropertyAsIntWithDefault("Ice.TCP.SndSize", dfltBufSize); + if(sizeRequested > 0) { // - // TODO: Warning? + // Try to set the buffer size. The kernel will silently adjust + // the size to an acceptable value. Then read the size back to + // get the size that was actually set. // - } - return false; -} - -bool -IceInternal::isPeerLocal(SOCKET fd) -{ - socklen_t remoteLen = static_cast<socklen_t>(sizeof(struct sockaddr_in)); - struct sockaddr_in remoteAddr; - if(getpeername(fd, reinterpret_cast<struct sockaddr*>(&remoteAddr), &remoteLen) == SOCKET_ERROR) - { - if(notConnected()) + setSendBufferSize(fd, sizeRequested); + int size = getSendBufferSize(fd); + if(size < sizeRequested) // Warn if the size that was set is less than the requested size. { - return false; - } - else - { - closeSocketNoThrow(fd); - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; + Ice::Warning out(logger); + out << "TCP send buffer size: requested size of " << sizeRequested << " adjusted to " << size; } } - return isLocalAddress(remoteAddr); } -#endif |