Amazing Grace

首页 新随笔 联系 管理

SeerAGV\Program.cs

using Seer.SeerSocket;

var seer = new SeerSocket();
var msg = seer.Send(0x0410,"""{"motor_names": ["motor1"]}""",19204);
Console.WriteLine(msg);


// System.Console.ReadKey();


SeerAGV\SeerAGV.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

SeerAGV\SeerSocket.cs

using System.Net.Sockets;
using System.Runtime.InteropServices;

namespace Seer.SeerSocket;
public struct SeerMessageHead
{
    public byte sync;  // 0x5A
    public byte version; // 0x01
    public ushort number; // 0-65536
    public uint length; // 数据区长度,json序列化数据长度
    public ushort type; // 报文的类型

#pragma warning disable 0414 //禁用警告
#pragma warning disable 0169 //禁用警告
    private readonly byte ref0;      //保留
    private readonly byte ref1;      //保留
    private readonly byte ref2;      //保留
    private readonly byte ref3;      //保留
    private readonly byte ref4;      //保留
    private readonly byte ref5;      //保留
#pragma warning restore 0414 //恢复警告
#pragma warning restore 0169 //恢复警告


    public SeerMessageHead()
    {
        this.sync = 0x5A;
        this.version = 0x01;
        this.number = 0x0001;
    }
    public SeerMessageHead(ushort type)
    {
        this.type = type;
    }





    public readonly byte[] ToBytes()
    {

        int size = Marshal.SizeOf(this);
        byte[] bytes = new byte[size];

        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(this, ptr, true);
        Marshal.Copy(ptr, bytes, 0, size);
        Marshal.FreeHGlobal(ptr);

        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(bytes, 2, 2);
            Array.Reverse(bytes, 4, 4);
            Array.Reverse(bytes, 8, 2);
        }
        return bytes;

    }


};



public class SeerSocket
{
    private readonly TcpClient statusClient;
    private readonly TcpClient? controlClient;
    private readonly TcpClient? navClient;
    private readonly TcpClient? configClient;
    private readonly TcpClient? otherClient;
    private bool isWrite=false;

    public SeerSocket(bool isWrite=false)
    {
        this.isWrite = isWrite;
        if (isWrite)
        {
            // 创建tcp连接
            this.statusClient = new TcpClient("", 19204);
            this.controlClient = new TcpClient("", 19205);
            this.navClient = new TcpClient("", 19206);
            this.configClient = new TcpClient("", 19207);
            this.otherClient = new TcpClient("", 19210);
        }
        else
        {
            this.statusClient = new TcpClient("", 19204);
        }

    }

    public string Send(ushort type, string msg = "", int port = 19204)
    {
        var msgBody = NormalStrToHexByte(msg);
        var msgHead = CreateMsgHead(type, (uint)msgBody.Length);
        if (port == 19204)
        {
            return this.SendRaw(msgHead, msgBody, statusClient);
        }
        else if (port == 19205 && this.isWrite)
        {
            return this.SendRaw(msgHead, msgBody, controlClient!);
        }
        else if (port == 19206 && this.isWrite)
        {
            return this.SendRaw(msgHead, msgBody, navClient!);
        }
        else if (port == 19207 && this.isWrite)
        {
            return this.SendRaw(msgHead, msgBody, configClient!);
        }
        else if (port == 19210 && this.isWrite)
        {
            return this.SendRaw(msgHead, msgBody, otherClient!);
        }
        return "";

    }

    private string SendRaw(byte[] msgHead, byte[] msgBody, TcpClient client)
    {
        try
        {
            if (!client.Connected) return "fail";
            // Console.WriteLine("connect successed!!!");
            NetworkStream serverStream = client.GetStream();
            serverStream.Write(msgHead, 0, msgHead.Length);
            serverStream.Write(msgBody, 0, msgBody.Length);
            serverStream.Flush();
            byte[] inStream = new byte[16];
            while (16 != serverStream.Read(inStream, 0, 16))
            {
                Thread.Sleep(20);
            }
            var recv_head = BytesToStructure<SeerMessageHead>(inStream);
            byte[] recvbyte = BitConverter.GetBytes(recv_head.length);
            Array.Reverse(recvbyte);
            var dsize = BitConverter.ToUInt32(recvbyte, 0);
            const int bufferSize = 512;
            List<byte> datalist = new List<byte>();
            int count = 0;
            while (true)
            {
                byte[] buffer = new byte[bufferSize];
                int readSize = serverStream.Read(buffer, 0, bufferSize);
                count += readSize;
                datalist.AddRange(buffer);
                if (count == dsize)
                {
                    break;
                }
                // Thread.Sleep(3);
            }
            // var content = BitConverter.ToString(SeerMessageHeadToBytes(recv_head)).Replace("-", " ");
            // Console.WriteLine(content);
            string resMsg = System.Text.Encoding.UTF8.GetString(datalist.ToArray());
            // System.Console.WriteLine(resMsg);
            return resMsg;
            // client.Close();
        }
        catch (SocketException)
        {

            return "fail";
        }
        catch (IOException)
        {
            return "fail";
        }
    }

    private T BytesToStructure<T>(byte[] bytesBuffer)
    {
        if (bytesBuffer.Length < Marshal.SizeOf(typeof(T)))
        {
            throw new ArgumentException("size error");
        }

        nint bufferHandler = Marshal.AllocHGlobal(bytesBuffer.Length);

        for (int index = 0; index < bytesBuffer.Length; index++)
        {
            Marshal.WriteByte(bufferHandler, index, bytesBuffer[index]);
        }

        // T? structObject = (T)Marshal.PtrToStructure(bufferHandler, typeof(T));
        T? structObject = Marshal.PtrToStructure<T>(bufferHandler);

        Marshal.FreeHGlobal(bufferHandler);

        if (structObject == null)
        {
            throw new InvalidOperationException("Failed to convert bytes to structure.");
        }

        return structObject!;
    }

    private byte[] NormalStrToHexByte(string str)
    {
        byte[] result = new byte[str.Length];

        byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);

        for (int i = 0; i < buffer.Length; i++)
        {
            result[i] = Convert.ToByte(buffer[i].ToString("X2"), 16);
        }
        return result;
    }

    private byte[] CreateMsgHead(ushort type, uint msgLen)
    {
        var msgHead = new SeerMessageHead
        {
            type = type,
            length = msgLen
        };
        return msgHead.ToBytes();
    }

    public static void PrintBytes(byte[] bytes)
    {
        foreach (byte b in bytes)
        {
            Console.Write("{0:X2} ", b);
        }

    }





}



posted on 2024-02-14 17:07  AmazingCookie  阅读(3)  评论(0编辑  收藏  举报