mirror of
https://github.com/S7NetPlus/s7netplus.git
synced 2026-02-17 14:28:25 +08:00
Revert "Use socket instead of TcpClient and stream."
Revert back to using Stream/TcpClient. High performance stuff is moved
to highperformancesockets branch. I think this is interesting, but i also
feel that this is premature optimization. I doubth that this will be a
performance bottleneck ofr the forseeable future.
This reverts commit 1b34716a30.
This commit is contained in:
@@ -4,7 +4,6 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using S7.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
@@ -14,22 +13,18 @@ namespace S7.Net.UnitTest
|
||||
[TestClass]
|
||||
public class ProtocolUnitTest
|
||||
{
|
||||
/*
|
||||
* Not sure how to implment these tests cleanly now. Probably need to spin up a TcpServer.
|
||||
[TestMethod]
|
||||
public void TPKT_Read()
|
||||
{
|
||||
Socket s = new Socket(SocketType.Stream, ProtocolType.Tcp);
|
||||
s.Send(StringToByteArray("0300002902f0803203000000010002001400000401ff0400807710000100000103000000033f8ccccd"));
|
||||
//Socket m = new MemoryStream();
|
||||
var t = TPKT.Read(s);
|
||||
Assert.AreEqual(0x03, t.Version);
|
||||
Assert.AreEqual(0x29, t.Length);
|
||||
//m.Position = 0;
|
||||
//t = TPKT.ReadAsync(m).Result;
|
||||
//Assert.AreEqual(0x03, t.Version);
|
||||
//Assert.AreEqual(0x29, t.Length);
|
||||
}
|
||||
[TestMethod]
|
||||
public void TPKT_Read()
|
||||
{
|
||||
var m = new MemoryStream(StringToByteArray("0300002902f0803203000000010002001400000401ff0400807710000100000103000000033f8ccccd"));
|
||||
var t = TPKT.Read(m);
|
||||
Assert.AreEqual(0x03, t.Version);
|
||||
Assert.AreEqual(0x29, t.Length);
|
||||
m.Position = 0;
|
||||
t = TPKT.ReadAsync(m).Result;
|
||||
Assert.AreEqual(0x03, t.Version);
|
||||
Assert.AreEqual(0x29, t.Length);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(TPKTInvalidException))]
|
||||
@@ -58,7 +53,7 @@ namespace S7.Net.UnitTest
|
||||
t = COTP.TSDU.ReadAsync(m).Result;
|
||||
Assert.IsTrue(expected.SequenceEqual(t));
|
||||
}
|
||||
*/
|
||||
|
||||
private static byte[] StringToByteArray(string hex)
|
||||
{
|
||||
return Enumerable.Range(0, hex.Length)
|
||||
@@ -66,7 +61,5 @@ namespace S7.Net.UnitTest
|
||||
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -162,15 +162,13 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestClass tc = new TestClass
|
||||
{
|
||||
BitVariable00 = true,
|
||||
BitVariable10 = true,
|
||||
DIntVariable = -100000,
|
||||
IntVariable = -15000,
|
||||
RealVariable = -154.789,
|
||||
DWordVariable = 850
|
||||
};
|
||||
TestClass tc = new TestClass();
|
||||
tc.BitVariable00 = true;
|
||||
tc.BitVariable10 = true;
|
||||
tc.DIntVariable = -100000;
|
||||
tc.IntVariable = -15000;
|
||||
tc.RealVariable = -154.789;
|
||||
tc.DWordVariable = 850;
|
||||
plc.WriteClass(tc, DB2);
|
||||
TestClass tc2 = new TestClass();
|
||||
// Values that are read from a class are stored inside the class itself, that is passed by reference
|
||||
@@ -191,15 +189,13 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestStruct tc = new TestStruct
|
||||
{
|
||||
BitVariable00 = true,
|
||||
BitVariable10 = true,
|
||||
DIntVariable = -100000,
|
||||
IntVariable = -15000,
|
||||
RealVariable = -154.789,
|
||||
DWordVariable = 850
|
||||
};
|
||||
TestStruct tc = new TestStruct();
|
||||
tc.BitVariable00 = true;
|
||||
tc.BitVariable10 = true;
|
||||
tc.DIntVariable = -100000;
|
||||
tc.IntVariable = -15000;
|
||||
tc.RealVariable = -154.789;
|
||||
tc.DWordVariable = 850;
|
||||
plc.WriteStruct(tc, DB2);
|
||||
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
|
||||
TestStruct tc2 = (TestStruct)plc.ReadStruct(typeof(TestStruct), DB2);
|
||||
@@ -219,33 +215,31 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestLongStruct tc = new TestLongStruct
|
||||
{
|
||||
IntVariable0 = 0,
|
||||
IntVariable1 = 1,
|
||||
IntVariable10 = 10,
|
||||
IntVariable11 = 11,
|
||||
IntVariable20 = 20,
|
||||
IntVariable21 = 21,
|
||||
IntVariable30 = 30,
|
||||
IntVariable31 = 31,
|
||||
IntVariable40 = 40,
|
||||
IntVariable41 = 41,
|
||||
IntVariable50 = 50,
|
||||
IntVariable51 = 51,
|
||||
IntVariable60 = 60,
|
||||
IntVariable61 = 61,
|
||||
IntVariable70 = 70,
|
||||
IntVariable71 = 71,
|
||||
IntVariable80 = 80,
|
||||
IntVariable81 = 81,
|
||||
IntVariable90 = 90,
|
||||
IntVariable91 = 91,
|
||||
IntVariable100 = 100,
|
||||
IntVariable101 = 101,
|
||||
IntVariable110 = 200,
|
||||
IntVariable111 = 201
|
||||
};
|
||||
TestLongStruct tc = new TestLongStruct();
|
||||
tc.IntVariable0 = 0;
|
||||
tc.IntVariable1 = 1;
|
||||
tc.IntVariable10 = 10;
|
||||
tc.IntVariable11 = 11;
|
||||
tc.IntVariable20 = 20;
|
||||
tc.IntVariable21 = 21;
|
||||
tc.IntVariable30 = 30;
|
||||
tc.IntVariable31 = 31;
|
||||
tc.IntVariable40 = 40;
|
||||
tc.IntVariable41 = 41;
|
||||
tc.IntVariable50 = 50;
|
||||
tc.IntVariable51 = 51;
|
||||
tc.IntVariable60 = 60;
|
||||
tc.IntVariable61 = 61;
|
||||
tc.IntVariable70 = 70;
|
||||
tc.IntVariable71 = 71;
|
||||
tc.IntVariable80 = 80;
|
||||
tc.IntVariable81 = 81;
|
||||
tc.IntVariable90 = 90;
|
||||
tc.IntVariable91 = 91;
|
||||
tc.IntVariable100 = 100;
|
||||
tc.IntVariable101 = 101;
|
||||
tc.IntVariable110 = 200;
|
||||
tc.IntVariable111 = 201;
|
||||
plc.WriteStruct(tc, DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
|
||||
@@ -285,33 +279,31 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestLongClass tc = new TestLongClass
|
||||
{
|
||||
IntVariable0 = 0,
|
||||
IntVariable1 = 1,
|
||||
IntVariable10 = 10,
|
||||
IntVariable11 = 11,
|
||||
IntVariable20 = 20,
|
||||
IntVariable21 = 21,
|
||||
IntVariable30 = 30,
|
||||
IntVariable31 = 31,
|
||||
IntVariable40 = 40,
|
||||
IntVariable41 = 41,
|
||||
IntVariable50 = 50,
|
||||
IntVariable51 = 51,
|
||||
IntVariable60 = 60,
|
||||
IntVariable61 = 61,
|
||||
IntVariable70 = 70,
|
||||
IntVariable71 = 71,
|
||||
IntVariable80 = 80,
|
||||
IntVariable81 = 81,
|
||||
IntVariable90 = 90,
|
||||
IntVariable91 = 91,
|
||||
IntVariable100 = 100,
|
||||
IntVariable101 = 101,
|
||||
IntVariable110 = 200,
|
||||
IntVariable111 = 201
|
||||
};
|
||||
TestLongClass tc = new TestLongClass();
|
||||
tc.IntVariable0 = 0;
|
||||
tc.IntVariable1 = 1;
|
||||
tc.IntVariable10 = 10;
|
||||
tc.IntVariable11 = 11;
|
||||
tc.IntVariable20 = 20;
|
||||
tc.IntVariable21 = 21;
|
||||
tc.IntVariable30 = 30;
|
||||
tc.IntVariable31 = 31;
|
||||
tc.IntVariable40 = 40;
|
||||
tc.IntVariable41 = 41;
|
||||
tc.IntVariable50 = 50;
|
||||
tc.IntVariable51 = 51;
|
||||
tc.IntVariable60 = 60;
|
||||
tc.IntVariable61 = 61;
|
||||
tc.IntVariable70 = 70;
|
||||
tc.IntVariable71 = 71;
|
||||
tc.IntVariable80 = 80;
|
||||
tc.IntVariable81 = 81;
|
||||
tc.IntVariable90 = 90;
|
||||
tc.IntVariable91 = 91;
|
||||
tc.IntVariable100 = 100;
|
||||
tc.IntVariable101 = 101;
|
||||
tc.IntVariable110 = 200;
|
||||
tc.IntVariable111 = 201;
|
||||
plc.WriteClass(tc, DB2);
|
||||
Assert.AreEqual(ErrorCode.NoError, plc.LastErrorCode);
|
||||
// Values that are read from a struct are stored in a new struct, returned by the funcion ReadStruct
|
||||
@@ -559,15 +551,13 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestClassWithPrivateSetters tc = new TestClassWithPrivateSetters
|
||||
{
|
||||
BitVariable00 = true,
|
||||
BitVariable10 = true,
|
||||
DIntVariable = -100000,
|
||||
IntVariable = -15000,
|
||||
RealVariable = -154.789,
|
||||
DWordVariable = 850
|
||||
};
|
||||
TestClassWithPrivateSetters tc = new TestClassWithPrivateSetters();
|
||||
tc.BitVariable00 = true;
|
||||
tc.BitVariable10 = true;
|
||||
tc.DIntVariable = -100000;
|
||||
tc.IntVariable = -15000;
|
||||
tc.RealVariable = -154.789;
|
||||
tc.DWordVariable = 850;
|
||||
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
@@ -609,15 +599,13 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestClass tc = new TestClass
|
||||
{
|
||||
BitVariable00 = true,
|
||||
BitVariable10 = true,
|
||||
DIntVariable = -100000,
|
||||
IntVariable = -15000,
|
||||
RealVariable = -154.789,
|
||||
DWordVariable = 850
|
||||
};
|
||||
TestClass tc = new TestClass();
|
||||
tc.BitVariable00 = true;
|
||||
tc.BitVariable10 = true;
|
||||
tc.DIntVariable = -100000;
|
||||
tc.IntVariable = -15000;
|
||||
tc.RealVariable = -154.789;
|
||||
tc.DWordVariable = 850;
|
||||
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
@@ -652,15 +640,13 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestClass tc = new TestClass
|
||||
{
|
||||
BitVariable00 = true,
|
||||
BitVariable10 = true,
|
||||
DIntVariable = -100000,
|
||||
IntVariable = -15000,
|
||||
RealVariable = -154.789,
|
||||
DWordVariable = 850
|
||||
};
|
||||
TestClass tc = new TestClass();
|
||||
tc.BitVariable00 = true;
|
||||
tc.BitVariable10 = true;
|
||||
tc.DIntVariable = -100000;
|
||||
tc.IntVariable = -15000;
|
||||
tc.RealVariable = -154.789;
|
||||
tc.DWordVariable = 850;
|
||||
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
@@ -707,15 +693,13 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestStruct ts = new TestStruct
|
||||
{
|
||||
BitVariable00 = true,
|
||||
BitVariable10 = true,
|
||||
DIntVariable = -100000,
|
||||
IntVariable = -15000,
|
||||
RealVariable = -154.789,
|
||||
DWordVariable = 850
|
||||
};
|
||||
TestStruct ts = new TestStruct();
|
||||
ts.BitVariable00 = true;
|
||||
ts.BitVariable10 = true;
|
||||
ts.DIntVariable = -100000;
|
||||
ts.IntVariable = -15000;
|
||||
ts.RealVariable = -154.789;
|
||||
ts.DWordVariable = 850;
|
||||
|
||||
plc.WriteStruct(ts, DB2);
|
||||
|
||||
@@ -752,15 +736,13 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestClass tc = new TestClass
|
||||
{
|
||||
BitVariable00 = true,
|
||||
BitVariable10 = true,
|
||||
DIntVariable = -100000,
|
||||
IntVariable = -15000,
|
||||
RealVariable = -154.789,
|
||||
DWordVariable = 850
|
||||
};
|
||||
TestClass tc = new TestClass();
|
||||
tc.BitVariable00 = true;
|
||||
tc.BitVariable10 = true;
|
||||
tc.DIntVariable = -100000;
|
||||
tc.IntVariable = -15000;
|
||||
tc.RealVariable = -154.789;
|
||||
tc.DWordVariable = 850;
|
||||
plc.WriteClass(tc, DB2);
|
||||
|
||||
int expectedReadBytes = Types.Class.GetClassSize(tc);
|
||||
@@ -777,10 +759,8 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestClassWithArrays tc = new TestClassWithArrays
|
||||
{
|
||||
Bool = true
|
||||
};
|
||||
TestClassWithArrays tc = new TestClassWithArrays();
|
||||
tc.Bool = true;
|
||||
tc.BoolValues[1] = true;
|
||||
tc.Int = int.MinValue;
|
||||
tc.Ints[0] = int.MinValue;
|
||||
@@ -824,11 +804,9 @@ namespace S7.Net.UnitTest
|
||||
{
|
||||
Assert.IsTrue(plc.IsConnected, "Before executing this test, the plc must be connected. Check constructor.");
|
||||
|
||||
TestClassWithCustomType tc = new TestClassWithCustomType
|
||||
{
|
||||
Int = int.MinValue,
|
||||
CustomType = new CustomType()
|
||||
};
|
||||
TestClassWithCustomType tc = new TestClassWithCustomType();
|
||||
tc.Int = int.MinValue;
|
||||
tc.CustomType = new CustomType();
|
||||
tc.CustomType.Bools[1] = true;
|
||||
tc.CustomTypes[0] = new CustomType();
|
||||
tc.CustomTypes[1] = new CustomType();
|
||||
|
||||
@@ -47,11 +47,11 @@ namespace S7.Net
|
||||
/// Reads COTP TPDU (Transport protocol data unit) from the network stream
|
||||
/// See: https://tools.ietf.org/html/rfc905
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket to read from</param>
|
||||
/// <param name="stream">The socket to read from</param>
|
||||
/// <returns>COTP DPDU instance</returns>
|
||||
public static TPDU Read(Socket socket)
|
||||
public static TPDU Read(Stream stream)
|
||||
{
|
||||
var tpkt = TPKT.Read(socket);
|
||||
var tpkt = TPKT.Read(stream);
|
||||
if (tpkt.Length > 0) return new TPDU(tpkt);
|
||||
return null;
|
||||
}
|
||||
@@ -60,11 +60,11 @@ namespace S7.Net
|
||||
/// Reads COTP TPDU (Transport protocol data unit) from the network stream
|
||||
/// See: https://tools.ietf.org/html/rfc905
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket to read from</param>
|
||||
/// <param name="stream">The socket to read from</param>
|
||||
/// <returns>COTP DPDU instance</returns>
|
||||
public static async Task<TPDU> ReadAsync(Socket socket)
|
||||
public static async Task<TPDU> ReadAsync(Stream stream)
|
||||
{
|
||||
var tpkt = await TPKT.ReadAsync(socket);
|
||||
var tpkt = await TPKT.ReadAsync(stream);
|
||||
if (tpkt.Length > 0) return new TPDU(tpkt);
|
||||
return null;
|
||||
}
|
||||
@@ -91,11 +91,11 @@ namespace S7.Net
|
||||
/// Reads the full COTP TSDU (Transport service data unit)
|
||||
/// See: https://tools.ietf.org/html/rfc905
|
||||
/// </summary>
|
||||
/// <param name="Socket">The stream to read from</param>
|
||||
/// <param name="stream">The stream to read from</param>
|
||||
/// <returns>Data in TSDU</returns>
|
||||
public static byte[] Read(Socket Socket)
|
||||
public static byte[] Read(Stream stream)
|
||||
{
|
||||
var segment = TPDU.Read(Socket);
|
||||
var segment = TPDU.Read(stream);
|
||||
if (segment == null) return null;
|
||||
|
||||
var output = new MemoryStream(segment.Data.Length);
|
||||
@@ -103,7 +103,7 @@ namespace S7.Net
|
||||
|
||||
while (!segment.LastDataUnit)
|
||||
{
|
||||
segment = TPDU.Read(Socket);
|
||||
segment = TPDU.Read(stream);
|
||||
output.Write(segment.Data, (int)output.Position, segment.Data.Length);
|
||||
}
|
||||
return output.GetBuffer().Take((int)output.Position).ToArray();
|
||||
@@ -113,11 +113,11 @@ namespace S7.Net
|
||||
/// Reads the full COTP TSDU (Transport service data unit)
|
||||
/// See: https://tools.ietf.org/html/rfc905
|
||||
/// </summary>
|
||||
/// <param name="socket">The stream to read from</param>
|
||||
/// <param name="stream">The stream to read from</param>
|
||||
/// <returns>Data in TSDU</returns>
|
||||
public static async Task<byte[]> ReadAsync(Socket socket)
|
||||
public static async Task<byte[]> ReadAsync(Stream stream)
|
||||
{
|
||||
var segment = await TPDU.ReadAsync(socket);
|
||||
var segment = await TPDU.ReadAsync(stream);
|
||||
if (segment == null) return null;
|
||||
|
||||
var output = new MemoryStream(segment.Data.Length);
|
||||
@@ -125,7 +125,7 @@ namespace S7.Net
|
||||
|
||||
while (!segment.LastDataUnit)
|
||||
{
|
||||
segment = await TPDU.ReadAsync(socket);
|
||||
segment = await TPDU.ReadAsync(stream);
|
||||
output.Write(segment.Data, (int)output.Position, segment.Data.Length);
|
||||
}
|
||||
return output.GetBuffer().Take((int)output.Position).ToArray();
|
||||
|
||||
@@ -17,10 +17,9 @@ namespace S7.Net
|
||||
{
|
||||
private const int CONNECTION_TIMED_OUT_ERROR_CODE = 10060;
|
||||
|
||||
/// <summary>
|
||||
/// TCP Connection to device
|
||||
/// </summary>
|
||||
private Socket socket;
|
||||
//TCP connection to device
|
||||
private TcpClient tcpClient;
|
||||
private NetworkStream stream;
|
||||
|
||||
/// <summary>
|
||||
/// IP address of the PLC
|
||||
@@ -70,11 +69,11 @@ namespace S7.Net
|
||||
{
|
||||
try
|
||||
{
|
||||
if (socket == null)
|
||||
if (tcpClient == null)
|
||||
return false;
|
||||
|
||||
//TODO: Actually check communication by sending an empty TPDU
|
||||
return socket.Connected;
|
||||
return tcpClient.Connected;
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
@@ -120,9 +119,9 @@ namespace S7.Net
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
if (socket != null)
|
||||
if (tcpClient != null)
|
||||
{
|
||||
if (socket.Connected) socket.Close();
|
||||
if (tcpClient.Connected) tcpClient.Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -316,11 +316,6 @@ namespace S7.Net
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get S7 Package for value
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public byte[] GetPackage(object value)
|
||||
{
|
||||
switch (value.GetType().Name)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using S7.Net.Types;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -24,16 +23,16 @@ namespace S7.Net
|
||||
{
|
||||
await ConnectAsync();
|
||||
|
||||
await socket.SendAsync(GetCOPTConnectionRequest(CPU), 0, 22, SocketFlags.None);
|
||||
var response = await COTP.TPDU.ReadAsync(socket);
|
||||
await stream.WriteAsync(GetCOPTConnectionRequest(CPU), 0, 22);
|
||||
var response = await COTP.TPDU.ReadAsync(stream);
|
||||
if (response.PDUType != 0xd0) //Connect Confirm
|
||||
{
|
||||
throw new WrongNumberOfBytesException("Waiting for COTP connect confirm");
|
||||
}
|
||||
|
||||
await socket.SendAsync(GetS7ConnectionSetup(), 0, 25, SocketFlags.None);
|
||||
await stream.WriteAsync(GetS7ConnectionSetup(), 0, 25);
|
||||
|
||||
var s7data = await COTP.TSDU.ReadAsync(socket);
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream);
|
||||
if (s7data == null || s7data[1] != 0x03) //Check for S7 Ack Data
|
||||
{
|
||||
throw new WrongNumberOfBytesException("Waiting for S7 connection setup");
|
||||
@@ -43,9 +42,9 @@ namespace S7.Net
|
||||
|
||||
private async Task ConnectAsync()
|
||||
{
|
||||
IPEndPoint server = new IPEndPoint(IPAddress.Parse(IP), 102);
|
||||
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
await socket.ConnectAsync(server.Address, 102);
|
||||
tcpClient = new TcpClient();
|
||||
await tcpClient.ConnectAsync(IP, 102);
|
||||
stream = tcpClient.GetStream();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -225,9 +224,9 @@ namespace S7.Net
|
||||
package.Add(CreateReadDataRequestPackage(dataItem.DataType, dataItem.DB, dataItem.StartByteAdr, VarTypeToByteLength(dataItem.VarType, dataItem.Count)));
|
||||
}
|
||||
|
||||
socket.Send(package.Array, package.Array.Length, SocketFlags.None);
|
||||
await stream.WriteAsync(package.Array, 0, package.Array.Length);
|
||||
|
||||
var s7data = await COTP.TSDU.ReadAsync(socket);
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream); //TODO use Async
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
@@ -400,9 +399,9 @@ namespace S7.Net
|
||||
// package.Add(0x02); // datenart
|
||||
package.Add(CreateReadDataRequestPackage(dataType, db, startByteAdr, count));
|
||||
|
||||
await socket.SendAsync(package.Array, 0, package.Array.Length, SocketFlags.None);
|
||||
await stream.WriteAsync(package.Array, 0, package.Array.Length);
|
||||
|
||||
var s7data = await COTP.TSDU.ReadAsync(socket);
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
@@ -452,9 +451,9 @@ namespace S7.Net
|
||||
// now join the header and the data
|
||||
package.Add(value);
|
||||
|
||||
await socket.SendAsync(package.Array, 0, package.Array.Length, SocketFlags.None);
|
||||
await stream.WriteAsync(package.Array, 0, package.Array.Length);
|
||||
|
||||
var s7data = await COTP.TSDU.ReadAsync(socket);
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
{
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
@@ -502,9 +501,9 @@ namespace S7.Net
|
||||
// now join the header and the data
|
||||
package.Add(value);
|
||||
|
||||
await socket.SendAsync(package.Array, 0, package.Array.Length, SocketFlags.None);
|
||||
await stream.WriteAsync(package.Array, 0, package.Array.Length);
|
||||
|
||||
var s7data = await COTP.TSDU.ReadAsync(socket);
|
||||
var s7data = await COTP.TSDU.ReadAsync(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using S7.Net.Types;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -26,16 +25,16 @@ namespace S7.Net
|
||||
}
|
||||
try
|
||||
{
|
||||
socket.Send(GetCOPTConnectionRequest(CPU), 0, 22, SocketFlags.None);
|
||||
var response = COTP.TPDU.Read(socket);
|
||||
stream.Write(GetCOPTConnectionRequest(CPU), 0, 22);
|
||||
var response = COTP.TPDU.Read(stream);
|
||||
if (response.PDUType != 0xd0) //Connect Confirm
|
||||
{
|
||||
throw new WrongNumberOfBytesException("Waiting for COTP connect confirm");
|
||||
}
|
||||
|
||||
socket.Send(GetS7ConnectionSetup(), 0, 25, SocketFlags.None);
|
||||
stream.Write(GetS7ConnectionSetup(), 0, 25);
|
||||
|
||||
var s7data = COTP.TSDU.Read(socket);
|
||||
var s7data = COTP.TSDU.Read(stream);
|
||||
if (s7data == null || s7data[1] != 0x03) //Check for S7 Ack Data
|
||||
{
|
||||
throw new WrongNumberOfBytesException("Waiting for S7 connection setup");
|
||||
@@ -55,10 +54,9 @@ namespace S7.Net
|
||||
{
|
||||
try
|
||||
{
|
||||
IPEndPoint server = new IPEndPoint(IPAddress.Parse(IP), 102);
|
||||
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
socket.Connect(server);
|
||||
return ErrorCode.NoError;
|
||||
tcpClient = new TcpClient();
|
||||
tcpClient.Connect(IP, 102);
|
||||
stream = tcpClient.GetStream();
|
||||
}
|
||||
catch (SocketException sex)
|
||||
{
|
||||
@@ -269,13 +267,12 @@ namespace S7.Net
|
||||
public ErrorCode WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, bool value)
|
||||
{
|
||||
if (bitAdr < 0 || bitAdr > 7)
|
||||
throw new Exception(string.Format("Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid", bitAdr));
|
||||
throw new InvalidAddressException(string.Format("Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid", bitAdr));
|
||||
|
||||
ErrorCode lastError = WriteBitWithASingleRequest(dataType, db, startByteAdr, bitAdr, value);
|
||||
if (lastError != ErrorCode.NoError)
|
||||
{
|
||||
return lastError;
|
||||
}
|
||||
return lastError; }
|
||||
|
||||
return ErrorCode.NoError;
|
||||
}
|
||||
@@ -351,9 +348,7 @@ namespace S7.Net
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode WriteStruct(object structValue, int db, int startByteAdr = 0)
|
||||
{
|
||||
var bytes = Struct.ToBytes(structValue).ToList();
|
||||
var errCode = WriteBytes(DataType.DataBlock, db, startByteAdr, bytes.ToArray());
|
||||
return errCode;
|
||||
return WriteStructAsync(structValue, db, startByteAdr).Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -365,9 +360,7 @@ namespace S7.Net
|
||||
/// <returns>NoError if it was successful, or the error is specified</returns>
|
||||
public ErrorCode WriteClass(object classValue, int db, int startByteAdr = 0)
|
||||
{
|
||||
var bytes = Class.ToBytes(classValue).ToList();
|
||||
var errCode = WriteBytes(DataType.DataBlock, db, startByteAdr, bytes.ToArray());
|
||||
return errCode;
|
||||
return WriteClassAsync(classValue, db, startByteAdr).Result;
|
||||
}
|
||||
|
||||
private byte[] ReadBytesWithSingleRequest(DataType dataType, int db, int startByteAdr, int count)
|
||||
@@ -382,9 +375,9 @@ namespace S7.Net
|
||||
// package.Add(0x02); // datenart
|
||||
package.Add(CreateReadDataRequestPackage(dataType, db, startByteAdr, count));
|
||||
|
||||
socket.Send(package.Array, 0, package.Array.Length, SocketFlags.None);
|
||||
stream.Write(package.Array, 0, package.Array.Length);
|
||||
|
||||
var s7data = COTP.TSDU.Read(socket);
|
||||
var s7data = COTP.TSDU.Read(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
@@ -436,9 +429,9 @@ namespace S7.Net
|
||||
// now join the header and the data
|
||||
package.Add(value);
|
||||
|
||||
socket.Send(package.Array, package.Array.Length, SocketFlags.None);
|
||||
stream.Write(package.Array, 0, package.Array.Length);
|
||||
|
||||
var s7data = COTP.TSDU.Read(socket);
|
||||
var s7data = COTP.TSDU.Read(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
{
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
@@ -485,9 +478,9 @@ namespace S7.Net
|
||||
// now join the header and the data
|
||||
package.Add(value);
|
||||
|
||||
socket.Send(package.Array, package.Array.Length, SocketFlags.None);
|
||||
stream.Write(package.Array, 0, package.Array.Length);
|
||||
|
||||
var s7data = COTP.TSDU.Read(socket);
|
||||
var s7data = COTP.TSDU.Read(stream);
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
@@ -509,6 +502,7 @@ namespace S7.Net
|
||||
/// DataItems must not be more than 20 (protocol restriction) and bytes must not be more than 200 + 22 of header (protocol restriction).
|
||||
/// </summary>
|
||||
/// <param name="dataItems">List of dataitems that contains the list of variables that must be read. Maximum 20 dataitems are accepted.</param>
|
||||
[Obsolete("Use ReadMultipleVarsAsync. Note: different function signature")]
|
||||
public void ReadMultipleVars(List<DataItem> dataItems)
|
||||
{
|
||||
int cntBytes = dataItems.Sum(dataItem => VarTypeToByteLength(dataItem.VarType, dataItem.Count));
|
||||
@@ -531,10 +525,10 @@ namespace S7.Net
|
||||
{
|
||||
package.Add(CreateReadDataRequestPackage(dataItem.DataType, dataItem.DB, dataItem.StartByteAdr, VarTypeToByteLength(dataItem.VarType, dataItem.Count)));
|
||||
}
|
||||
|
||||
stream.Write(package.Array, 0, package.Array.Length);
|
||||
|
||||
socket.Send(package.Array, package.Array.Length, SocketFlags.None);
|
||||
|
||||
var s7data = COTP.TSDU.Read(socket);
|
||||
var s7data = COTP.TSDU.Read(stream); //TODO use Async
|
||||
if (s7data == null || s7data[14] != 0xff)
|
||||
throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
|
||||
|
||||
@@ -79,13 +79,12 @@
|
||||
<Compile Include="Conversion.cs" />
|
||||
<Compile Include="COTP.cs" />
|
||||
<Compile Include="Enums.cs" />
|
||||
<Compile Include="PLC.cs" />
|
||||
<Compile Include="PLCAsynchronous.cs" />
|
||||
<Compile Include="Plc.cs" />
|
||||
<Compile Include="PlcAsynchronous.cs" />
|
||||
<Compile Include="PLCExceptions.cs" />
|
||||
<Compile Include="PLCHelpers.cs" />
|
||||
<Compile Include="PLCSynchronous.cs" />
|
||||
<Compile Include="PlcHelpers.cs" />
|
||||
<Compile Include="PlcSynchronous.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SocketExtension.cs" />
|
||||
<Compile Include="TPKT.cs" />
|
||||
<Compile Include="Types\Bit.cs" />
|
||||
<Compile Include="Types\Boolean.cs" />
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace S7.Net
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Extensions to socket for using awaitable socket operations
|
||||
/// </summary>
|
||||
public static class SocketExtensions
|
||||
{
|
||||
|
||||
/// <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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
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>
|
||||
/// https://blogs.msdn.microsoft.com/pfxteam/2011/12/15/awaiting-socket-operations/
|
||||
/// </summary>
|
||||
/// <param name="socket"></param>
|
||||
/// <param name="addresses"></param>
|
||||
/// <param name="port"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<int> ConnectAsync(this Socket socket, System.Net.IPAddress addresses, int port)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<int>(socket);
|
||||
socket.BeginConnect(addresses, port, 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,12 @@ namespace S7.Net
|
||||
/// <summary>
|
||||
/// Reads a TPKT from the socket
|
||||
/// </summary>
|
||||
/// <param name="socket">The stream to read from</param>
|
||||
/// <param name="stream">The stream to read from</param>
|
||||
/// <returns>TPKT Instance</returns>
|
||||
public static TPKT Read(Socket socket)
|
||||
public static TPKT Read(Stream stream)
|
||||
{
|
||||
var buf = new byte[4];
|
||||
int len = socket.Receive(buf, 0, 4, SocketFlags.None);
|
||||
int len = stream.Read(buf, 0, 4);
|
||||
if (len < 4) throw new TPKTInvalidException("TPKT is incomplete / invalid");
|
||||
var pkt = new TPKT
|
||||
{
|
||||
@@ -35,7 +35,7 @@ namespace S7.Net
|
||||
if (pkt.Length > 0)
|
||||
{
|
||||
pkt.Data = new byte[pkt.Length - 4];
|
||||
len = socket.Receive(pkt.Data, 0, pkt.Length - 4, SocketFlags.None);
|
||||
len = stream.Read(pkt.Data, 0, pkt.Length - 4);
|
||||
if (len < pkt.Length - 4)
|
||||
throw new TPKTInvalidException("TPKT is incomplete / invalid");
|
||||
}
|
||||
@@ -45,12 +45,12 @@ namespace S7.Net
|
||||
/// <summary>
|
||||
/// Reads a TPKT from the socket Async
|
||||
/// </summary>
|
||||
/// <param name="socket">The stream to read from</param>
|
||||
/// <param name="stream">The stream to read from</param>
|
||||
/// <returns>Task TPKT Instace</returns>
|
||||
public static async Task<TPKT> ReadAsync(Socket socket)
|
||||
public static async Task<TPKT> ReadAsync(Stream stream)
|
||||
{
|
||||
var buf = new byte[4];
|
||||
int len = await socket.ReceiveAsync(buf, 0, 4, SocketFlags.None);
|
||||
int len = await stream.ReadAsync(buf, 0, 4);
|
||||
if (len < 4) throw new TPKTInvalidException("TPKT is incomplete / invalid");
|
||||
var pkt = new TPKT
|
||||
{
|
||||
@@ -61,7 +61,7 @@ namespace S7.Net
|
||||
if (pkt.Length > 0)
|
||||
{
|
||||
pkt.Data = new byte[pkt.Length - 4];
|
||||
len = await socket.ReceiveAsync(pkt.Data, 0, pkt.Length - 4, SocketFlags.None);
|
||||
len = await stream.ReadAsync(pkt.Data, 0, pkt.Length - 4);
|
||||
if (len < pkt.Length - 4) throw new TPKTInvalidException("TPKT is incomplete / invalid");
|
||||
}
|
||||
return pkt;
|
||||
|
||||
Reference in New Issue
Block a user