IceInternal::TcpAcceptor::TcpAcceptor(const TcpEndpointIPtr& endpoint, const ProtocolInstancePtr& instance, const string& host, int port) : _endpoint(endpoint), _instance(instance), _addr(getAddressForServer(host, port, _instance->protocolSupport(), instance->preferIPv6())) #ifdef ICE_USE_IOCP , _acceptFd(INVALID_SOCKET), _info(SocketOperationRead) #endif { #ifdef SOMAXCONN _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN); #else _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511); #endif _fd = createServerSocket(false, _addr, instance->protocolSupport()); #ifdef ICE_USE_IOCP _acceptBuf.resize((sizeof(sockaddr_storage) + 16) * 2); #endif setBlock(_fd, false); setTcpBufSize(_fd, _instance->properties(), _instance->logger()); #ifndef _WIN32 // // Enable SO_REUSEADDR on Unix platforms to allow re-using the // socket even if it's in the TIME_WAIT state. On Windows, // this doesn't appear to be necessary and enabling // SO_REUSEADDR would actually not be a good thing since it // allows a second process to bind to an address even it's // already bound by another process. // // TODO: using SO_EXCLUSIVEADDRUSE on Windows would probably // be better but it's only supported by recent Windows // versions (XP SP2, Windows Server 2003). // setReuseAddress(_fd, true); #endif }
IceInternal::TcpAcceptor::TcpAcceptor(const TcpEndpointIPtr& endpoint, const ProtocolInstancePtr& instance, const string& host, int port) : _endpoint(endpoint), _instance(instance), _addr(getAddressForServer(host, port, _instance->protocolSupport(), instance->preferIPv6())) #ifdef ICE_USE_IOCP , _acceptFd(INVALID_SOCKET), _info(SocketOperationRead) #endif { _backlog = instance->properties()->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN); #if defined(ICE_OS_WINRT) _fd = ref new StreamSocketListener(); safe_cast<StreamSocketListener^>(_fd)->ConnectionReceived += ref new TypedEventHandler<StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^>( [=](StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^ args) { IceUtil::Mutex::Lock lock(_mutex); if(_fd == INVALID_SOCKET) // Acceptor was closed. { closeSocket(args->Socket); return; } _accepted.push_back(args->Socket); // // If the acceptor is waiting for a socket to be accepted, notify // the selector that the acceptor is ready for "read". This will // in turn caused finishAccept() and accept() to be called by the // thread pool. If the acceptor isn't ready to accept the socket, // it is just queued, when startAccept is called it will be dequed. // if(_acceptPending) { completed(SocketOperationRead); _acceptPending = false; } });