C#中通过TCP socket方法发送一个bit类型的数据
Sending a bit type data through TCP socket method in C#
第一次在这个平台提问。
请随时指出我应该做什么或避免什么才能变得更好,谢谢。
我正在尝试将 Struct 对象发送到 MES(制造执行系统)以更改我工作站的状态。
这是数据结构的说明(2.2):
下面的 C# 代码就是我所做的。我确定我已经连接到MES系统了,但是Status没有变化,我想可能是我传输的数据格式有关。
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using TcpClient = NetCoreServer.TcpClient;
//the Struct of data
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct StateOfRobotino
{
public int ResourceID;
public byte SPSType;
public byte State_info;
}
StateOfRobotino robotino10 = new StateOfRobotino();
robotino10.ResourceID = 10;
robotino10.SPSType = 2;
robotino10.State_info = 0b10000001; //MES mode, Auto
byte[] b_robotino10 = getBytes(robotino10);
//Convert Struct type to byte array through Marshal
byte[] getBytes(StateOfRobotino str)
{
int size = Marshal.SizeOf(str);
byte[] arr = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
return arr;
}
我怀疑的一件事是我的结构中的第三个数据,我可以只用一个字节(State_info)来表示 8 位数据吗?如果没有,我该怎么办?或者有没有其他方法可以尝试传输此类数据?
谢谢。
获取字节数组的编组方法应该有效。
现在进入你的数据结构:
ResourceID Int 0
SPSType Byte 2
Auto Mode Bit 3.0
... Bit 3.n
MES Mode Bit 3.7
请注意包含 0、2 和 3.x
的数字列
ResourceID
看起来占用 字节 0 和 1。 Int
中的两个字节表示您的 PLC 是 16 位的。 C# 的 int
是 32 位的,占用四个字节。您需要明确指定 Int16
或 UInt16
(可能是无符号的 UInt16
,除非您的 MES 期望来自 PLC 的负数)。
它们也称为 short
或 ushort
,但在处理外部系统时通过指定 16 位来更明确地减少混淆总是好的。
SPSType
只是一个字节。
其余标记为3.0 ... 3.7
。这是占用字节 3 的 8 位 (0..7) 的表示法。这意味着,是的,您应该发送 一个包含所有位的字节 。请记住,位 0 是 right-most 位,因此 0b00000001
是自动模式,0b10000000
是 MES 模式。
第一次在这个平台提问。 请随时指出我应该做什么或避免什么才能变得更好,谢谢。
我正在尝试将 Struct 对象发送到 MES(制造执行系统)以更改我工作站的状态。 这是数据结构的说明(2.2):
下面的 C# 代码就是我所做的。我确定我已经连接到MES系统了,但是Status没有变化,我想可能是我传输的数据格式有关。
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using TcpClient = NetCoreServer.TcpClient;
//the Struct of data
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct StateOfRobotino
{
public int ResourceID;
public byte SPSType;
public byte State_info;
}
StateOfRobotino robotino10 = new StateOfRobotino();
robotino10.ResourceID = 10;
robotino10.SPSType = 2;
robotino10.State_info = 0b10000001; //MES mode, Auto
byte[] b_robotino10 = getBytes(robotino10);
//Convert Struct type to byte array through Marshal
byte[] getBytes(StateOfRobotino str)
{
int size = Marshal.SizeOf(str);
byte[] arr = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
return arr;
}
我怀疑的一件事是我的结构中的第三个数据,我可以只用一个字节(State_info)来表示 8 位数据吗?如果没有,我该怎么办?或者有没有其他方法可以尝试传输此类数据? 谢谢。
获取字节数组的编组方法应该有效。
现在进入你的数据结构:
ResourceID Int 0
SPSType Byte 2
Auto Mode Bit 3.0
... Bit 3.n
MES Mode Bit 3.7
请注意包含 0、2 和 3.x
的数字列ResourceID
看起来占用 字节 0 和 1。Int
中的两个字节表示您的 PLC 是 16 位的。 C# 的int
是 32 位的,占用四个字节。您需要明确指定Int16
或UInt16
(可能是无符号的UInt16
,除非您的 MES 期望来自 PLC 的负数)。它们也称为
short
或ushort
,但在处理外部系统时通过指定 16 位来更明确地减少混淆总是好的。SPSType
只是一个字节。其余标记为
3.0 ... 3.7
。这是占用字节 3 的 8 位 (0..7) 的表示法。这意味着,是的,您应该发送 一个包含所有位的字节 。请记住,位 0 是 right-most 位,因此0b00000001
是自动模式,0b10000000
是 MES 模式。