public TelnetStreamWatcherBase(TelnetStreamWatcherOptions options) { this.Options = options; Listener = TcpIp.CreateListener(new TcpListenParam(async(listener, sock) => { try { Con.WriteDebug($"TelnetStreamWatcher({this.ToString()}: Connected: {sock.EndPointInfo._GetObjectDump()}"); using (var destStream = sock.GetStream()) { if (sock.Info.Ip.RemoteIPAddress == null || Options.IPAccessFilter(sock.Info.Ip.RemoteIPAddress) == false) { Con.WriteDebug($"TelnetStreamWatcher({this.ToString()}: Access denied: {sock.EndPointInfo._GetObjectDump()}"); await destStream.WriteAsync("You are not allowed to access to this service.\r\n\r\n"._GetBytes_Ascii()); await Task.Delay(100); return; } using (var pipePoint = await SubscribeImplAsync()) { // ソケットから Enter キー入力を待機する Task keyInputTask = TaskUtil.StartAsyncTaskAsync(async() => { using StreamReader lineReader = new StreamReader(destStream); while (true) { string?line = await lineReader.ReadLineAsync(); if (line == null) { break; } line = line.Trim(); if (line._IsSamei("s")) { // Socket リストの表示 var list = LocalNet.GetSockList().OrderBy(x => x.Connected); StringWriter w = new StringWriter(); w.WriteLine(); foreach (var sock in list) { string tmp = sock._GetObjectDump(); w.WriteLine(tmp); } w.WriteLine(); w.WriteLine($"Total sockets: {list.Count()}"); w.WriteLine(); byte[] data = w.ToString()._GetBytes_Ascii(); var pipe = pipePoint; if (pipe.CounterPart != null) { lock (pipe.CounterPart.StreamWriter.LockObj) { if (pipe.CounterPart.StreamWriter.NonStopWriteWithLock(data, false, FastStreamNonStopWriteMode.DiscardExistingData) != 0) { // To avoid deadlock, CompleteWrite() must be called from other thread. // (CompleteWrite() ==> Disconnect ==> Socket Log will recorded ==> ReceiveLog() ==> this function will be called!) TaskUtil.StartSyncTaskAsync(() => pipe.CounterPart.StreamWriter.CompleteWrite(false), false, false)._LaissezFaire(true); } } } } else { // GC Dbg.WriteLine($"Manual GC is called by the administrator."); long start = FastTick64.Now; Dbg.GcCollect(); long end = FastTick64.Now; long spentTime = end - start; Dbg.WriteLine($"Manual GC Took Time: {spentTime} msecs."); } } }); try { // ソケットに対して、pipePoint のストリームをそのまま非同期で流し込む using (var pipeStub = pipePoint.GetNetAppProtocolStub()) using (var srcStream = pipeStub.GetStream()) { await srcStream.CopyToAsync(destStream, sock.GrandCancel); } } finally { await UnsubscribeImplAsync(pipePoint); await pipePoint.CleanupAsync(new DisconnectedException()); await keyInputTask._TryAwait(noDebugMessage: true); } } } } finally { Con.WriteDebug($"TelnetStreamWatcher({this.ToString()}: Disconnected: {sock.EndPointInfo._GetObjectDump()}"); } }, "TelnetStreamWatcher", this.Options.EndPoints.ToArray())); this.AddIndirectDisposeLink(this.Listener); }