static async Task Test_Pipe_SslStream_Client(CancellationToken cancel) { string hostname = "news.goo.ne.jp"; int port = 443; AsyncCleanuperLady lady = new AsyncCleanuperLady(); try { var tcp = new FastPalTcpProtocolStub(lady, cancel: cancel); var sock = await tcp.ConnectAsync(hostname, port); FastSslProtocolStack ssl = new FastSslProtocolStack(lady, sock.UpperEnd, null, null, cancel); var sslClientOptions = new PalSslClientAuthenticationOptions() { TargetHost = hostname, ValidateRemoteCertificateProc = (cert) => { return(true); }, }; var ssl_sock = await ssl.SslStartClient(sslClientOptions, cancel); var app = ssl_sock.GetFastAppProtocolStub(cancel); app.AttachHandle.SetStreamReceiveTimeout(1000); var st = app.GetStream().GetPalNetworkStream(); var tcp_info = ssl_sock.Info.GetValue <ILayerInfoTcpEndPoint>(); var ssl_info = ssl_sock.Info.GetValue <ILayerInfoSsl>(); WriteLine($"Connected. {tcp_info.LocalIPAddress}:{tcp_info.LocalPort} -> {tcp_info.RemoteIPAddress}:{tcp_info.RemotePort}"); StreamWriter w = new StreamWriter(st); w.AutoFlush = true; await w.WriteAsync( "GET / HTTP/1.0\r\n" + $"HOST: {hostname}\r\n\r\n" ); StreamReader r = new StreamReader(st); while (true) { string s = await r.ReadLineAsync(); if (s == null) { break; } WriteLine(s); } } finally { await lady; } }
static async Task Test_Pipe_TCP_Client(CancellationToken cancel) { AsyncCleanuperLady lady = new AsyncCleanuperLady(); try { var tcp = new FastPalTcpProtocolStub(lady, cancel: cancel); var sock = await tcp.ConnectAsync("www.google.com", 80, null); var app = sock.GetFastAppProtocolStub(cancel); var st = app.GetStream().GetPalNetworkStream(); app.AttachHandle.SetStreamTimeout(2000, -1); WriteLine("Connected."); StreamWriter w = new StreamWriter(st); w.AutoFlush = true; await w.WriteAsync( "GET / HTTP/1.0\r\n" + "HOST: www.google.com\r\n\r\n" ); StreamReader r = new StreamReader(st); while (true) { string s = await r.ReadLineAsync(); if (s == null) { break; } WriteLine(s); } } finally { await lady; } }
static async Task pipe_socket_udp_proc() { UdpClient uc = new UdpClient(AddressFamily.InterNetwork); uc.Client.Bind(new IPEndPoint(IPAddress.Any, 0)); Console.WriteLine($"port: {((IPEndPoint)uc.Client.LocalEndPoint).Port}"); IPAddress server_ip = IPAddress.Parse("130.158.6.60"); AsyncCleanuperLady lady = new AsyncCleanuperLady(); try { FastPipe pipe = new FastPipe(lady); var reader = pipe.B_UpperSide.DatagramReader; var writer = pipe.B_UpperSide.DatagramWriter; using (FastPipeEndSocketWrapper w = new FastPipeEndSocketWrapper(lady, pipe.A_LowerSide, new PalSocket(uc.Client))) { try { long next_send = 0; FastPipeNonblockStateHelper helper = new FastPipeNonblockStateHelper(reader, writer); long now = FastTick64.Now; while (true) { if (next_send == 0 || next_send <= now) { next_send = now + 500; lock (writer.LockObj) { writer.Enqueue(new Datagram(new byte[] { (byte)'B' }, new IPEndPoint(server_ip, 5004))); } writer.CompleteWrite(); } List <Datagram> pkts; lock (reader.LockObj) { pkts = reader.DequeueAll(out _); } reader.CompleteRead(); foreach (var pkt in pkts) { //Dbg.Where($"recv: {pkt.Data.Length} {pkt.IPEndPoint}"); string tmp = Encoding.ASCII.GetString(pkt.Data.Span); var ep = UdpAccel.ParseIPAndPortStr(tmp); //Console.WriteLine(ep); writer.Enqueue(pkt); writer.CompleteWrite(); } if (await helper.WaitIfNothingChanged((int)(next_send - now))) { now = FastTick64.Now; } //Dbg.Where(); } Dbg.Where("Disconnected."); } finally { await w.AsyncCleanuper; } } } finally { await lady; } }
async Task <Result> ClientSingleConnectionAsync(Direction dir, AsyncManualResetEvent fireMeWhenReady, CancellationToken cancel) { Result ret = new Result(); AsyncCleanuperLady lady = new AsyncCleanuperLady(); try { var tcp = new FastPalTcpProtocolStub(lady, cancel: cancel); var sock = await tcp.ConnectAsync(ServerIP, ServerPort, cancel, ConnectTimeout); var app = sock.GetFastAppProtocolStub(); var attachHandle = app.AttachHandle; var st = app.GetStream(); if (dir == Direction.Recv) { app.AttachHandle.SetStreamReceiveTimeout(RecvTimeout); } try { var hello = await st.ReceiveAllAsync(16); Dbg.Where(); if (Encoding.ASCII.GetString(hello.Span).StartsWith("TrafficServer\r\n") == false) { throw new ApplicationException("Target server is not a Traffic Server."); } Dbg.Where(); //throw new ApplicationException("aaaa" + dir.ToString()); fireMeWhenReady.Set(); cancel.ThrowIfCancellationRequested(); await WebSocketHelper.WaitObjectsAsync( manualEvents : ClientStartEvent.ToSingleArray(), cancels : cancel.ToSingleArray() ); long tickStart = FastTick64.Now; long tickEnd = tickStart + this.TimeSpan; var sendData = new MemoryBuffer <byte>(); sendData.WriteBool8(dir == Direction.Recv); sendData.WriteUInt64(SessionId); sendData.WriteSInt64(TimeSpan); await st.SendAsync(sendData); if (dir == Direction.Recv) { RefInt totalRecvSize = new RefInt(); while (true) { long now = FastTick64.Now; if (now >= tickEnd) { break; } await WebSocketHelper.WaitObjectsAsync( tasks : st.FastReceiveAsync(totalRecvSize : totalRecvSize).ToSingleArray(), timeout : (int)(tickEnd - now), exceptions : ExceptionWhen.TaskException | ExceptionWhen.CancelException); ret.NumBytesDownload += totalRecvSize; } } else { attachHandle.SetStreamReceiveTimeout(Timeout.Infinite); while (true) { long now = FastTick64.Now; if (now >= tickEnd) { break; } /*await WebSocketHelper.WaitObjectsAsync( * tasks: st.FastSendAsync(SendData, flush: true).ToSingleArray(), * timeout: (int)(tick_end - now), * exceptions: ExceptionWhen.TaskException | ExceptionWhen.CancelException);*/ await st.FastSendAsync(SendData, flush : true); } Task recvResult = Task.Run(async() => { var recvMemory = await st.ReceiveAllAsync(8); MemoryBuffer <byte> recvMemoryBuf = recvMemory; ret.NumBytesUpload = recvMemoryBuf.ReadSInt64(); st.Disconnect(); }); Task sendSurprise = Task.Run(async() => { byte[] surprise = new byte[260]; surprise.AsSpan().Fill((byte)'!'); while (true) { await st.SendAsync(surprise); await WebSocketHelper.WaitObjectsAsync( manualEvents: sock.Pipe.OnDisconnectedEvent.ToSingleArray(), timeout: 200); } }); await WhenAll.Await(false, recvResult, sendSurprise); await recvResult; } st.Disconnect(); Dbg.Where(); return(ret); } catch (Exception ex) { Dbg.Where(ex.Message); ExceptionQueue.Add(ex); throw; } } finally { await lady; } }
public async Task <Result> RunClientAsync() { if (IsServerMode) { throw new ApplicationException("Server mode"); } if (Once.IsFirstCall() == false) { throw new ApplicationException("You cannot reuse the object."); } WriteLine("Client mode start"); ExceptionQueue = new ExceptionQueue(); SessionId = WebSocketHelper.RandUInt64(); List <Task <Result> > tasks = new List <Task <Result> >(); List <AsyncManualResetEvent> readyEvents = new List <AsyncManualResetEvent>(); AsyncCleanuperLady lady = new AsyncCleanuperLady(); try { CancelWatcher cancelWatcher = new CancelWatcher(lady, this.Cancel); for (int i = 0; i < NumConnection; i++) { Direction dir; if (Mode == ModeFlag.Download) { dir = Direction.Recv; } else if (Mode == ModeFlag.Upload) { dir = Direction.Send; } else { dir = ((i % 2) == 0) ? Direction.Recv : Direction.Send; } AsyncManualResetEvent readyEvent = new AsyncManualResetEvent(); var t = ClientSingleConnectionAsync(dir, readyEvent, cancelWatcher.CancelToken); ExceptionQueue.RegisterWatchedTask(t); tasks.Add(t); readyEvents.Add(readyEvent); } try { using (var whenAllReady = new WhenAll(readyEvents.Select(x => x.WaitAsync()))) { await WebSocketHelper.WaitObjectsAsync( tasks : tasks.Append(whenAllReady.WaitMe).ToArray(), cancels : cancelWatcher.CancelToken.ToSingleArray(), manualEvents : ExceptionQueue.WhenExceptionAdded.ToSingleArray()); } Cancel.ThrowIfCancellationRequested(); ExceptionQueue.ThrowFirstExceptionIfExists(); ExceptionQueue.WhenExceptionAdded.CallbackList.AddSoftCallback(x => { cancelWatcher.Cancel(); }); using (new DelayAction(lady, TimeSpan * 3 + 180 * 1000, x => { cancelWatcher.Cancel(); })) { ClientStartEvent.Set(true); using (var whenAllCompleted = new WhenAll(tasks)) { await WebSocketHelper.WaitObjectsAsync( tasks : whenAllCompleted.WaitMe.ToSingleArray(), cancels : cancelWatcher.CancelToken.ToSingleArray() ); await whenAllCompleted.WaitMe; } } Result ret = new Result(); ret.Span = TimeSpan; foreach (var r in tasks.Select(x => x.Result)) { ret.NumBytesDownload += r.NumBytesDownload; ret.NumBytesUpload += r.NumBytesUpload; } ret.NumBytesTotal = ret.NumBytesUpload + ret.NumBytesDownload; ret.BpsUpload = (long)((double)ret.NumBytesUpload * 1000.0 * 8.0 / (double)ret.Span * 1514.0 / 1460.0); ret.BpsDownload = (long)((double)ret.NumBytesDownload * 1000.0 * 8.0 / (double)ret.Span * 1514.0 / 1460.0); ret.BpsTotal = ret.BpsUpload + ret.BpsDownload; return(ret); } catch (Exception ex) { await Task.Yield(); ExceptionQueue.Add(ex); } finally { cancelWatcher.Cancel(); try { await Task.WhenAll(tasks); } catch { } } ExceptionQueue.ThrowFirstExceptionIfExists(); } finally { await lady; } Dbg.Where(); return(null); }
public async Task RunServerAsync() { if (IsServerMode == false) { throw new ApplicationException("Client mode"); } if (Once.IsFirstCall() == false) { throw new ApplicationException("You cannot reuse the object."); } using (var sessions = new GroupManager <ulong, SessionData>( onNewGroup: (key, state) => { Dbg.Where($"New session: {key}"); return(new SessionData()); }, onDeleteGroup: (key, ctx, state) => { Dbg.Where($"Delete session: {key}"); })) { AsyncCleanuperLady glady = new AsyncCleanuperLady(); FastPalTcpListener listener = new FastPalTcpListener(glady, async(lx, sock) => { AsyncCleanuperLady lady = new AsyncCleanuperLady(); try { Console.WriteLine($"Connected {sock.Info.Tcp.RemoteIPAddress}:{sock.Info.Tcp.RemotePort} -> {sock.Info.Tcp.LocalIPAddress}:{sock.Info.Tcp.LocalPort}"); var app = sock.GetFastAppProtocolStub(); var st = app.GetStream(); var attachHandle = app.AttachHandle; attachHandle.SetStreamReceiveTimeout(RecvTimeout); await st.SendAsync(Encoding.ASCII.GetBytes("TrafficServer\r\n\0")); MemoryBuffer <byte> buf = await st.ReceiveAsync(17); Direction dir = buf.ReadBool8() ? Direction.Send : Direction.Recv; ulong sessionId = 0; long timespan = 0; try { sessionId = buf.ReadUInt64(); timespan = buf.ReadSInt64(); } catch { } long recvEndTick = FastTick64.Now + timespan; if (timespan == 0) { recvEndTick = long.MaxValue; } using (var session = sessions.Enter(sessionId)) { using (var delay = new DelayAction(lady, (int)(Math.Min(timespan * 3 + 180 * 1000, int.MaxValue)), x => app.Disconnect(new TimeoutException()))) { if (dir == Direction.Recv) { RefInt refTmp = new RefInt(); long totalSize = 0; while (true) { var ret = await st.FastReceiveAsync(totalRecvSize: refTmp); if (ret.Count == 0) { break; } totalSize += refTmp; if (ret[0].Span[0] == (byte)'!') { break; } if (FastTick64.Now >= recvEndTick) { break; } } attachHandle.SetStreamReceiveTimeout(Timeout.Infinite); attachHandle.SetStreamSendTimeout(60 * 5 * 1000); session.Context.NoMoreData = true; while (true) { MemoryBuffer <byte> sendBuf = new MemoryBuffer <byte>(); sendBuf.WriteSInt64(totalSize); await st.SendAsync(sendBuf); await Task.Delay(100); } } else { attachHandle.SetStreamReceiveTimeout(Timeout.Infinite); attachHandle.SetStreamSendTimeout(Timeout.Infinite); while (true) { if (sessionId == 0 || session.Context.NoMoreData == false) { await st.SendAsync(SendData); } else { var recvMemory = await st.ReceiveAsync(); if (recvMemory.Length == 0) { break; } } } } } } } catch (Exception ex) { WriteLine(ex.GetSingleException().Message); } finally { Dbg.Where(); await lady; Dbg.Where(); } }); try { listener.Add(this.ServerPort, IPVersion.IPv4); listener.Add(this.ServerPort, IPVersion.IPv6); WriteLine("Listening."); await WebSocketHelper.WaitObjectsAsync(cancels : this.Cancel.ToSingleArray()); } finally { await glady; } } }