From 219c1cc71ad0d00677c33dfdfd04af27eda94fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20J=C3=A4ger?= Date: Fri, 18 May 2018 08:43:44 +0200 Subject: [PATCH] Revert "Use high performance wrapper" This reverts commit a3277133af228e3f9d860c6166b4e8563f34c6c7. --- S7.Net/PLCAsynchronous.cs | 10 +-- S7.Net/SocketExtension.cs | 140 +++++++++++++------------------------- S7.Net/TPKT.cs | 13 ++-- 3 files changed, 60 insertions(+), 103 deletions(-) diff --git a/S7.Net/PLCAsynchronous.cs b/S7.Net/PLCAsynchronous.cs index 4134023..5ac01d4 100644 --- a/S7.Net/PLCAsynchronous.cs +++ b/S7.Net/PLCAsynchronous.cs @@ -24,14 +24,14 @@ namespace S7.Net { await ConnectAsync(); - await socket.SendAsync(GetCOPTConnectionRequest(CPU), 0, 22); + await socket.SendAsync(GetCOPTConnectionRequest(CPU), 0, 22, SocketFlags.None); var response = await COTP.TPDU.ReadAsync(socket); if (response.PDUType != 0xd0) //Connect Confirm { throw new WrongNumberOfBytesException("Waiting for COTP connect confirm"); } - await socket.SendAsync(GetS7ConnectionSetup(), 0, 25); + await socket.SendAsync(GetS7ConnectionSetup(), 0, 25, SocketFlags.None); var s7data = await COTP.TSDU.ReadAsync(socket); if (s7data == null || s7data[1] != 0x03) //Check for S7 Ack Data @@ -400,7 +400,7 @@ namespace S7.Net // package.Add(0x02); // datenart package.Add(CreateReadDataRequestPackage(dataType, db, startByteAdr, count)); - await socket.SendAsync(package.Array, 0, package.Array.Length); + await socket.SendAsync(package.Array, 0, package.Array.Length, SocketFlags.None); var s7data = await COTP.TSDU.ReadAsync(socket); if (s7data == null || s7data[14] != 0xff) @@ -452,7 +452,7 @@ namespace S7.Net // now join the header and the data package.Add(value); - await socket.SendAsync(package.Array, 0, package.Array.Length); + await socket.SendAsync(package.Array, 0, package.Array.Length, SocketFlags.None); var s7data = await COTP.TSDU.ReadAsync(socket); if (s7data == null || s7data[14] != 0xff) @@ -502,7 +502,7 @@ namespace S7.Net // now join the header and the data package.Add(value); - await socket.SendAsync(package.Array, 0, package.Array.Length); + await socket.SendAsync(package.Array, 0, package.Array.Length, SocketFlags.None); var s7data = await COTP.TSDU.ReadAsync(socket); if (s7data == null || s7data[14] != 0xff) diff --git a/S7.Net/SocketExtension.cs b/S7.Net/SocketExtension.cs index a51b71c..24fa345 100644 --- a/S7.Net/SocketExtension.cs +++ b/S7.Net/SocketExtension.cs @@ -1,6 +1,5 @@ using System; using System.Net.Sockets; -using System.Net; using System.IO; using System.Collections.Generic; using System.Linq; @@ -11,55 +10,59 @@ using System.Runtime.CompilerServices; namespace S7.Net { - public static class SocketExtensionsAsync + + /// + /// Extensions to socket for using awaitable socket operations + /// + public static class SocketExtensions { - public static SocketAwaitable ReceiveAsync(this Socket socket, - SocketAwaitable awaitable) + + /// + /// https://blogs.msdn.microsoft.com/pfxteam/2011/12/15/awaiting-socket-operations/ + /// + /// + /// + /// + /// + /// + /// + public static Task ReceiveAsync( + this Socket socket, byte[] buffer, int offset, int size, + SocketFlags socketFlags) { - awaitable.Reset(); - if (!socket.ReceiveAsync(awaitable.m_eventArgs)) - awaitable.m_wasCompleted = true; - return awaitable; + var tcs = new TaskCompletionSource(socket); + socket.BeginReceive(buffer, offset, size, socketFlags, iar => + { + var t = (TaskCompletionSource)iar.AsyncState; + var s = (Socket)t.Task.AsyncState; + try { t.TrySetResult(s.EndReceive(iar)); } + catch (Exception exc) { t.TrySetException(exc); } + }, tcs); + return tcs.Task; } - public static SocketAwaitable SendAsync(this Socket socket, - SocketAwaitable awaitable) + /// + /// https://blogs.msdn.microsoft.com/pfxteam/2011/12/15/awaiting-socket-operations/ + /// + /// + /// + /// + /// + /// + /// + public static Task SendAsync( + this Socket socket, byte[] buffer, int offset, int size, + SocketFlags socketFlags) { - awaitable.Reset(); - if (!socket.SendAsync(awaitable.m_eventArgs)) - awaitable.m_wasCompleted = true; - return awaitable; - } - - public static SocketAwaitable ConnectAsync(this Socket socket, - SocketAwaitable awaitable) - { - awaitable.Reset(); - if (!socket.ConnectAsync(awaitable.m_eventArgs)) - awaitable.m_wasCompleted = true; - return awaitable; - } - - public static async Task ReadAsync(this Socket s, byte[] buffer, int offset, int count) - { - // Reusable SocketAsyncEventArgs and awaitable wrapper - var args = new SocketAsyncEventArgs(); - args.SetBuffer(buffer, offset, count); - var awaitable = new SocketAwaitable(args); - - await s.ReceiveAsync(awaitable); - return args.BytesTransferred; - } - - public static async Task SendAsync(this Socket s, byte[] buffer, int offset, int count) - { - // Reusable SocketAsyncEventArgs and awaitable wrapper - var args = new SocketAsyncEventArgs(); - args.SetBuffer(buffer, offset, count); - var awaitable = new SocketAwaitable(args); - - await s.SendAsync(awaitable); - return args.BytesTransferred; + var tcs = new TaskCompletionSource(socket); + socket.BeginSend(buffer, offset, size, socketFlags, iar => + { + var t = (TaskCompletionSource)iar.AsyncState; + var s = (Socket)t.Task.AsyncState; + try { t.TrySetResult(s.EndReceive(iar)); } + catch (Exception exc) { t.TrySetException(exc); } + }, tcs); + return tcs.Task; } /// @@ -81,51 +84,6 @@ namespace S7.Net }, tcs); return tcs.Task; } + } - - public sealed class SocketAwaitable : INotifyCompletion - { - private readonly static Action SENTINEL = () => { }; - - internal bool m_wasCompleted; - internal Action m_continuation; - internal SocketAsyncEventArgs m_eventArgs; - - public SocketAwaitable(SocketAsyncEventArgs eventArgs) - { - m_eventArgs = eventArgs ?? throw new ArgumentNullException("eventArgs"); - eventArgs.Completed += delegate - { - (m_continuation ?? Interlocked.CompareExchange( - ref m_continuation, SENTINEL, null))?.Invoke(); - }; - } - - internal void Reset() - { - m_wasCompleted = false; - m_continuation = null; - } - - public SocketAwaitable GetAwaiter() { return this; } - - public bool IsCompleted { get { return m_wasCompleted; } } - - public void OnCompleted(Action continuation) - { - if (m_continuation == SENTINEL || - Interlocked.CompareExchange( - ref m_continuation, continuation, null) == SENTINEL) - { - Task.Run(continuation); - } - } - - public void GetResult() - { - //if (m_eventArgs.SocketError != SocketError.Success) - // throw new SocketException((int)m_eventArgs.SocketError); - } - } - } diff --git a/S7.Net/TPKT.cs b/S7.Net/TPKT.cs index 57a2f22..f264e9b 100644 --- a/S7.Net/TPKT.cs +++ b/S7.Net/TPKT.cs @@ -16,8 +16,6 @@ namespace S7.Net public int Length; public byte[] Data; - private static byte[] sharedBuffer = new byte[4096]; - /// /// Reads a TPKT from the socket /// @@ -51,18 +49,19 @@ namespace S7.Net /// Task TPKT Instace public static async Task ReadAsync(Socket socket) { - int len = await socket.ReadAsync(sharedBuffer, 0, 4); + var buf = new byte[4]; + int len = await socket.ReceiveAsync(buf, 0, 4, SocketFlags.None); if (len < 4) throw new TPKTInvalidException("TPKT is incomplete / invalid"); var pkt = new TPKT { - Version = sharedBuffer[0], - Reserved1 = sharedBuffer[1], - Length = sharedBuffer[2] * 256 + sharedBuffer[3] //BigEndian + Version = buf[0], + Reserved1 = buf[1], + Length = buf[2] * 256 + buf[3] //BigEndian }; if (pkt.Length > 0) { pkt.Data = new byte[pkt.Length - 4]; - len = await socket.ReadAsync(pkt.Data, 0, pkt.Length - 4); + len = await socket.ReceiveAsync(pkt.Data, 0, pkt.Length - 4, SocketFlags.None); if (len < pkt.Length - 4) throw new TPKTInvalidException("TPKT is incomplete / invalid"); } return pkt;