/// <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); }
/// <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>(); }
/// <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); }
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."); }
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()); }
public LoopbackPipe(LoopbackAcceptor acceptor, LoopbackEndPoint endpoint, IoHandler handler) { _acceptor = acceptor; _endpoint = endpoint; _handler = handler; }