Revert "Use high performance wrapper"

This reverts commit a3277133af.
This commit is contained in:
Thomas Jäger
2018-05-18 08:43:44 +02:00
parent a3277133af
commit 219c1cc71a
3 changed files with 60 additions and 103 deletions

View File

@@ -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)

View File

@@ -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
/// <summary>
/// Extensions to socket for using awaitable socket operations
/// </summary>
public static class SocketExtensions
{
public static SocketAwaitable ReceiveAsync(this Socket socket,
SocketAwaitable awaitable)
/// <summary>
/// https://blogs.msdn.microsoft.com/pfxteam/2011/12/15/awaiting-socket-operations/
/// </summary>
/// <param name="socket"></param>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="size"></param>
/// <param name="socketFlags"></param>
/// <returns></returns>
public static Task<int> 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<int>(socket);
socket.BeginReceive(buffer, offset, size, socketFlags, iar =>
{
var t = (TaskCompletionSource<int>)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)
/// <summary>
/// https://blogs.msdn.microsoft.com/pfxteam/2011/12/15/awaiting-socket-operations/
/// </summary>
/// <param name="socket"></param>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="size"></param>
/// <param name="socketFlags"></param>
/// <returns></returns>
public static Task<int> 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<int> 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<int> 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<int>(socket);
socket.BeginSend(buffer, offset, size, socketFlags, iar =>
{
var t = (TaskCompletionSource<int>)iar.AsyncState;
var s = (Socket)t.Task.AsyncState;
try { t.TrySetResult(s.EndReceive(iar)); }
catch (Exception exc) { t.TrySetException(exc); }
}, tcs);
return tcs.Task;
}
/// <summary>
@@ -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);
}
}
}

View File

@@ -16,8 +16,6 @@ namespace S7.Net
public int Length;
public byte[] Data;
private static byte[] sharedBuffer = new byte[4096];
/// <summary>
/// Reads a TPKT from the socket
/// </summary>
@@ -51,18 +49,19 @@ namespace S7.Net
/// <returns>Task TPKT Instace</returns>
public static async Task<TPKT> 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;