예제 #1
0
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
}
예제 #2
0
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;
                    }
                });