예제 #1
0
        /// <inheritdoc/>
        protected override IEnumerable <EndPoint> BindInternal(IEnumerable <EndPoint> localEndPoints)
        {
            HashSet <EndPoint> newLocalEPs = new HashSet <EndPoint>();

            lock (BoundHandlers)
            {
                foreach (EndPoint ep in localEndPoints)
                {
                    LoopbackEndPoint localEP = ep as LoopbackEndPoint;
                    if (localEP == null || localEP.Port == 0)
                    {
                        localEP = null;
                        for (Int32 i = 10000; i < Int32.MaxValue; i++)
                        {
                            LoopbackEndPoint newLocalEP = new LoopbackEndPoint(i);
                            if (!BoundHandlers.ContainsKey(newLocalEP) && !newLocalEPs.Contains(newLocalEP))
                            {
                                localEP = newLocalEP;
                                break;
                            }
                        }

                        if (localEP == null)
                        {
                            throw new IOException("No port available.");
                        }
                    }
                    else if (localEP.Port < 0)
                    {
                        throw new IOException("Bind port number must be 0 or above.");
                    }
                    else if (BoundHandlers.ContainsKey(localEP))
                    {
                        throw new IOException("Address already bound: " + localEP);
                    }

                    newLocalEPs.Add(localEP);
                }

                foreach (LoopbackEndPoint localEP in newLocalEPs)
                {
                    if (BoundHandlers.ContainsKey(localEP))
                    {
                        foreach (LoopbackEndPoint ep in newLocalEPs)
                        {
                            BoundHandlers.Remove(ep);
                        }
                        throw new IOException("Duplicate local address: " + localEP);
                    }
                    else
                    {
                        BoundHandlers[localEP] = new LoopbackPipe(this, localEP, Handler);
                    }
                }
            }

            _idleStatusChecker.Start();

            return(newLocalEPs);
        }
예제 #2
0
 /// <summary>
 /// Constructor for server-side session.
 /// </summary>
 public LoopbackSession(LoopbackSession remoteSession, LoopbackPipe entry)
     : base(entry.Acceptor)
 {
     Config                = new DefaultLoopbackSessionConfig();
     _lock                 = remoteSession._lock;
     _localEP              = remoteSession._remoteEP;
     _remoteEP             = remoteSession._localEP;
     _filterChain          = new LoopbackFilterChain(this);
     _remoteSession        = remoteSession;
     _receivedMessageQueue = new ConcurrentQueue <Object>();
 }
예제 #3
0
 /// <summary>
 /// Constructor for client-side session.
 /// </summary>
 public LoopbackSession(IoService service, LoopbackEndPoint localEP,
                        IoHandler handler, LoopbackPipe remoteEntry)
     : base(service)
 {
     Config                = new DefaultLoopbackSessionConfig();
     _lock                 = new Byte[0];
     _localEP              = localEP;
     _remoteEP             = remoteEntry.Endpoint;
     _filterChain          = new LoopbackFilterChain(this);
     _receivedMessageQueue = new ConcurrentQueue <Object>();
     _remoteSession        = new LoopbackSession(this, remoteEntry);
 }
예제 #4
0
        private static LoopbackEndPoint NextLocalEP()
        {
            lock (takenLocalEPs)
            {
                if (nextLocalPort >= 0)
                {
                    nextLocalPort = -1;
                }
                for (Int32 i = 0; i < Int32.MaxValue; i++)
                {
                    LoopbackEndPoint answer = new LoopbackEndPoint(nextLocalPort--);
                    if (!takenLocalEPs.Contains(answer))
                    {
                        takenLocalEPs.Add(answer);
                        return(answer);
                    }
                }
            }

            throw new IOException("Can't assign a Loopback port.");
        }
예제 #5
0
        public void TestSessionCreated()
        {
            Semaphore        semaphore = new Semaphore(0, 10);
            StringBuilder    sb        = new StringBuilder();
            LoopbackAcceptor acceptor  = new LoopbackAcceptor();
            LoopbackEndPoint lep       = new LoopbackEndPoint(12345);

            acceptor.SessionCreated += (s, e) =>
            {
                // pretend we are doing some time-consuming work. For
                // performance reasons, you would never want to do time
                // consuming work in sessionCreated.
                // However, this increases the likelihood of the timing bug.
                Thread.Sleep(1000);
                sb.Append("A");
            };
            acceptor.SessionOpened   += (s, e) => sb.Append("B");
            acceptor.MessageReceived += (s, e) => sb.Append("C");
            acceptor.SessionClosed   += (s, e) =>
            {
                sb.Append("D");
                semaphore.Release();
            };

            acceptor.Bind(lep);

            LoopbackConnector connector = new LoopbackConnector();

            connector.FilterChain.AddLast("executor", new ExecutorFilter());
            IConnectFuture future = connector.Connect(lep);

            future.Await();
            future.Session.Write(IoBuffer.Wrap(new byte[1])).Await();
            future.Session.Close(false).Await();

            semaphore.WaitOne(TimeSpan.FromSeconds(1));
            acceptor.Unbind(lep);
            Assert.AreEqual(1, future.Session.WrittenBytes);
            Assert.AreEqual("ABCD", sb.ToString());
        }
예제 #6
0
 public LoopbackPipe(LoopbackAcceptor acceptor, LoopbackEndPoint endpoint, IoHandler handler)
 {
     _acceptor = acceptor;
     _endpoint = endpoint;
     _handler  = handler;
 }