mirror of
https://github.com/S7NetPlus/s7netplus.git
synced 2026-02-17 22:38:27 +08:00
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user