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;