C# 二进制编码

问题描述 投票:0回答:1

我想根据第一张图的数据类型为第二张图的参数准备一个订单包,但是我无法正确设置规则,无法进行正确的转换和排列。如何正确设置捆绑包创建?

根据这段代码,当我将包传输到服务器时,服务器关闭连接并且没有返回响应,因为我设置的包不正确。

图1.

1. Picture

图2.

2. Picture

一些固定值:

  • 订单代币:101
  • 订单簿ID:3437892
  • 侧吉林(B/S/T):B
  • 吉林数量:1个
  • 价格 girin(十进制格式):2.9
  • 客户帐户 girin:DE-102001
private static void SendOrder()
{
    try
    {
        Console.WriteLine("Order Token girin:");
        string orderToken = Console.ReadLine().PadRight(14);

        Console.WriteLine("Order book ID girin:");
        int orderBookId = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("Side girin (B/S/T):");
        string side = Console.ReadLine();

        Console.WriteLine("Quantity girin:");
        int quantity = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("Price girin (Decimal formatında):");
        decimal price = Convert.ToDecimal(Console.ReadLine());

        Console.WriteLine("Client-Account girin:");
        string clientAccount = Console.ReadLine().PadRight(16);

        // Diğer sabit alanlar
        string customerInfo = "".PadRight(15);
        string exchangeInfo = "".PadRight(32);
        byte openClose = 0; // 0 = Default for the account

        // Veriyi baytlara dönüştürme
        byte[] orderTokenBytes = Encoding.ASCII.GetBytes(orderToken);
        byte[] orderBookIdBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(orderBookId));
        byte[] quantityBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(quantity));
        byte[] priceBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Convert.ToInt32(price * 10000))); // Fiyatı 4 bayt olarak ayarlama
        byte[] displayQuantityBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(0L)); // 8 baytlı ve 0 olarak ayarlama

        // Paket oluşturma
        byte[] orderPacketBytes = new byte[114];
        orderPacketBytes[0] = (byte)'O';
        orderTokenBytes.CopyTo(orderPacketBytes, 1);
        Array.Copy(orderBookIdBytes, 0, orderPacketBytes, 15, 4); // 4 baytlık Order book ID
        orderPacketBytes[19] = (byte)side[0];
        Array.Copy(quantityBytes, 0, orderPacketBytes, 20, 4); // 8 baytlık Quantity
        Array.Copy(priceBytes, 0, orderPacketBytes, 28, 4); // 4 baytlık Price
        orderPacketBytes[32] = (byte)'0'; // Time In Force (0 = Day)
        orderPacketBytes[33] = openClose; // Open Close (0 = Default)
        Encoding.ASCII.GetBytes(clientAccount).CopyTo(orderPacketBytes, 34);
        Encoding.ASCII.GetBytes(customerInfo).CopyTo(orderPacketBytes, 50);
        Encoding.ASCII.GetBytes(exchangeInfo).CopyTo(orderPacketBytes, 65);
        displayQuantityBytes.CopyTo(orderPacketBytes, 97); // Display Quantity
        orderPacketBytes[105] = (byte)'1'; // Client Category (1 = Client)
        orderPacketBytes[106] = (byte)'0'; // OffHours (0 = Normal hours)
        Encoding.ASCII.GetBytes("".PadRight(7)).CopyTo(orderPacketBytes, 107); // Reserved

        byte[] packet = CreateOrderPacket(orderPacketBytes);

        _networkStream.Write(packet, 0, packet.Length);
        LogMessage("Sipariş girme isteği gönderildi.");
        LogMessage("Giden: " + BitConverter.ToString(packet));
        LogMessage("Giden (Metin): " + Encoding.ASCII.GetString(packet));

        Task.Run(() => BeginReadingOrderResponse(_cancellationTokenSource.Token));
    }
    catch (Exception ex)
    {
        LogMessage("Sipariş girme isteği gönderilirken hata: " + ex.Message);
    }
}

private static byte[] CreateOrderPacket(byte[] messageBytes)
{
    byte[] lengthBytes = BitConverter.GetBytes((ushort)(messageBytes.Length + 1));
    if (BitConverter.IsLittleEndian)
        Array.Reverse(lengthBytes);
    byte[] packet = new byte[lengthBytes.Length + messageBytes.Length + 1]; // Length + Type + Payload
    lengthBytes.CopyTo(packet, 0);
    messageBytes.CopyTo(packet, lengthBytes.Length);
    packet[packet.Length - 1] = (byte)'\n'; // Terminating newline for SoupBinTCP
    return packet;
}

private static async Task BeginReadingOrderResponse(CancellationToken token)
{
    try
    {
        byte[] buffer = new byte[4096];
        while (_isConnected && !token.IsCancellationRequested)
        {
            int bytesRead = await _networkStream.ReadAsync(buffer, 0, buffer.Length, token);
            if (bytesRead == 0)
            {
                LogMessage("Sunucu bağlantıyı kesti.");
                Disconnect();
                break;
            }
            ProcessOrderPacket(buffer, bytesRead);
        }
    }
    catch (OperationCanceledException)
    {
        LogMessage("Okuma işlemi iptal edildi.");
    }
    catch (Exception ex)
    {
        LogMessage("Yanıt okunurken hata: " + ex.Message);
        Disconnect();
    }
}

seniro dev 创建了代码,但它不起作用

c# encoding ascii bitconverter
1个回答
0
投票

这是完全错误的。

if (BitConverter.IsLittleEndian)
    Array.Reverse(lengthBytes);

这会反转整个数组,但您需要的是反转各个数字字段的字节序。 在本机代码中,这通常由

ntohs
ntohl
完成。 C# 确实有
IPAddress.HostToNetworkOrder()
,它完全可以满足您的需要,它只是被包裹在一个非常不相关的名称中。

© www.soinside.com 2019 - 2024. All rights reserved.