【问题标题】:How to read Big Endian strings如何读取大端字符串
【发布时间】:2014-08-16 01:21:12
【问题描述】:

我在这个领域非常缺乏经验,我需要从不是我的服务器接收一个字符串,这里是协议:

所有发往Scratch 的消息都必须以这种格式发送到端口 42001:

在零字节之后是要传递的字符串消息的长度,以 32 位 big-Endian 数(4 个字节)的形式给出。 最后是字符串消息,其长度是消息大小的长度。 像这样:

[大小][大小][大小][大小][字符串消息(大小字节长)]

我的程序能够连接和接收数据,但我无法将其转换为字符串。

public class SynchronousSocketClient {

public static void StartClient(IPAddress IP) {
    // Data buffer for incoming data.
    byte[] bytes = new byte[1024];

    // Connect to a remote device.
    try {
        // Establish the remote endpoint for the socket.

        IPEndPoint remoteEP = new IPEndPoint(IP, 42001);

        // Create a TCP/IP  socket.
        Socket sender = new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, ProtocolType.Tcp );

        // Connect the socket to the remote endpoint. Catch any errors.
        try {
            sender.Connect(remoteEP);

            Console.WriteLine("Socket connected to {0}",
                sender.RemoteEndPoint.ToString());

            // Receive the response from the remote device.
            int bytesRec = sender.Receive(bytes);
            Console.WriteLine("Bytes Recibidos : {0}", bytesRec);

            //HERE IS THE PROBLEM...

            Console.WriteLine("Echoed test = "+
                System.Text.Encoding.BigEndianUnicode.GetString(bytes, 0, bytesRec));

           /* // Encode the data string into a byte array.
            byte[] msg = Encoding.ASCII.GetBytes("broadcast \"YES\"");

            // Send the data through the socket.
            int bytesSent = sender.Send(msg);*/



            // Release the socket.
            sender.Shutdown(SocketShutdown.Both);
            sender.Close();

        } catch (ArgumentNullException ane) {
            Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
        } catch (SocketException se) {
            Console.WriteLine("SocketException : {0}",se.ToString());
        } catch (Exception e) {
            Console.WriteLine("Unexpected exception : {0}", e.ToString());
        }

    } catch (Exception e) {
        Console.WriteLine( e.ToString());
    }
}}

【问题讨论】:

  • 你还需要知道文本编码;它提到了吗?也许是 UTF8?
  • 请将 "cant convert it to string" 替换为您的代码、示例输入、预期输出和实际输出。 @Marc:来自Scratch Wiki: Remote Sensors Protocol“单词和字符串以UTF-8编码。”.
  • 字符串不是“大端”。仅前 4 个字节。
  • @CodeCaster 很酷,它越来越成为一个相当安全的默认值
  • 单词和字符串以 UTF-8 编码。

标签: c# string stream


【解决方案1】:

首先,读取长度:

byte[] buffer = ...
ReadExactly(stream, buffer, 0, 4);

void ReadExactly(Stream stream, byte[] data, int offset, int count)
{
    int read;
    while(count > 0 && (read = stream.Read(data, offset, count)) > 0)
    {
        offset += read;
        count -= read;
    }
    if(count != 0) throw new EndOfStreamException();
}

现在解析那个 big-endian 样式:

int len = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];

现在读取有效载荷;例如:

ReadExactly(stream, buffer, 0, len);

并获取字符串,你需要知道它的编码;我在这里假设 UTF-8:

string s = Encoding.UTF8.GetString(buffer, 0, len);

【讨论】:

  • ...如果您需要现成的东西,请检查:highfieldtales.wordpress.com/2014/03/27/…
  • 谢谢,但我不知道如何在我的代码中使用它...你能解释一下吗?
  • @user 在套接字周围包裹一个 NetworkStream:工作完成
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-17
  • 2017-12-05
  • 1970-01-01
  • 2015-06-24
  • 2021-05-13
  • 1970-01-01
相关资源
最近更新 更多