Отправка данных битового типа через метод сокета TCP в C#

#c# #serialization #tcpclient

#c# #сериализация #tcpclient

Вопрос:

я впервые задаю вопросы на этой платформе. Не стесняйтесь указывать, что я должен делать или избегать, чтобы стать лучше, спасибо.

Я пытаюсь отправить объект Struct в MES (производственную исполнительную систему) для изменения статуса моей рабочей станции. Вот иллюстрация структуры данных (2.2):

1

И приведенный ниже код на C # — это то, что я сделал. Я уверен, что я подключился к системе MES, но статус просто не изменился, и я подумал, что причина может быть связана с форматом передаваемых данных.

 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-битных данных? Если нет, то как я должен поступить? Или есть какой-либо другой способ, которым я могу попытаться передать такие данные?
Спасибо.

Ответ №1:

Метод сортировки для получения вашего массива байтов должен работать.

Теперь перейдем к вашей структуре данных:

 ResourceID  Int   0
SPSType     Byte  2
Auto Mode   Bit   3.0
...         Bit   3.n
MES Mode    Bit   3.7
  

Я обращаю ваше внимание на числовой столбец, содержащий 0, 2 и 3.x

  1. ResourceID похоже, что они занимают байты 0 и 1. Два байта в an Int указывают, что ваш ПЛК 16-разрядный. C # int является 32-разрядным, который занимает ЧЕТЫРЕ байта. Вам необходимо явно указать либо Int16 или UInt16 (возможно, беззнаковое UInt16 , если вы MES не ожидаете отрицательного числа от ПЛК).

    Они также известны как short или ushort , но всегда приятно быть более явным, указывая 16-разрядность при работе с внешними системами, чтобы минимизировать путаницу.

  2. SPSType это просто байт.

  3. Остальные из них помечены как 3.0 ... 3.7 . Это обозначение для 8 бит (0 ..7), которые занимают байт 3. Что означает, что да, ожидается, что вы отправите один байт, содержащий все биты. Имейте в виду, что бит 0 является самым правым битом, как 0b00000001 и AutoMode, и 0b10000000 является MESMode .

Комментарии:

1. В частности, спасибо за подсказку о 4 байтах нулей и структуре данных (INT на самом деле составляет 16 бит (2 байта)).