【问题标题】:Why doesn't Environment.NewLine work when converting between byte array and string为什么在字节数组和字符串之间转换时 Environment.NewLine 不起作用
【发布时间】:2023-03-13 19:47:01
【问题描述】:

我正在使用 TCP 在服务器和客户端之间发送数据。我发送一个字节流,所以我将字符串转换为字节数组,发送到客户端,然后将其转换回字符串。然后我将此字符串插入到一个多行文本框中,每个文本框后面都有Environment.NewLine。但是,没有出现新行。

我尝试了多种将字符串转换为数组并返回字符串的方法,结果都相同。 Environment.NewLine 不起作用。 \n\r 不起作用。

我尝试使用以下技术进行转换:

  1. Encoding.ASCII.GetString()Encoding.ASCII.GetBytes()
  2. Encoding.Unicode.GetString()Encoding.Unicode.GetBytes()
  3. 我还使用了以下网站上的代码:

    System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
    String to Byte Array Conversion in C# and VB.NET (and back)

我应该如何来回转换这些字符串以使其正常工作?我的客户目前是 C#,但将是生产中的 java。

编辑:

    AttachMessage(ByteArrayToStr(messageInByteArray)); // Doesn't work
    AttachMessage("TEST"); // works


    public void AttachMessage(string data)
    {
        textBox2.Text += data + Environment.NewLine;
    }

    public static string ByteArrayToStr(byte[] arr)
    {
        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
        return encoding.GetString(arr);
    }

    public static byte[] StrToByteArray(string str)
    {
        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
        return encoding.GetBytes(str);
    }

这是一个转换问题,因为它适用于未转换的字符串。

编辑 2:

public partial class Form1 : Form
{
    public volatile List<TcpClient> connectedClients;
    public volatile bool ServerOn;
    public volatile TcpListener server;
    public delegate void txtBoxDelegate(string data);
    public delegate void tcpCommand(string ipAddress);
    public delegate void chatMessageDelegate(byte[] message);

    public Form1()
    {
        InitializeComponent();
        connectedClients = new List<TcpClient>();
        ServerOn = false;
        server = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 6789);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (!ServerOn)
        {
            Thread serverThread = new Thread(new ThreadStart(TcpServer));
            serverThread.IsBackground = true;
            serverThread.Start();
            lblServerStatus.Text = "The server is On.";
            lblServerStatus.ForeColor = Color.Green;
            lstServerUpdates.Text = String.Empty;
            button1.Text = "Turn server Off";
            ServerOn = true;
        }
        else
        {
            ServerOn = false;
            lstServerUpdates.Text = "Server has been turned off.";
            lblServerStatus.Text = "The server is Off.";
            lblServerStatus.ForeColor = Color.Red;
        }
    }

    public static string ByteArrayToStr(byte[] arr)
    {
        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
        return encoding.GetString(arr);
    }

    public static byte[] StrToByteArray(string str)
    {
        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
        return encoding.GetBytes(str);
    }

    private void TcpServer()
    {
        printToTextBox("Starting TCP Server.");

        server.Start();
        while (ServerOn)
        {
            if (!server.Pending())
            {
                Thread.Sleep(10);
                continue;
            }
            TcpClient clientSocket = server.AcceptTcpClient();

            NetworkStream stream = clientSocket.GetStream();

            connectedClients.Add(clientSocket);

            Thread clientThread = new Thread(new ParameterizedThreadStart(ClientThreads));
            clientThread.Start(clientSocket);

            byte[] bytes = StrToByteArray("Successfully connected to the server.");

            stream.Write(bytes, 0, bytes.Length);
            printToTextBox("Client successfully connected to server.");
        }


        server.Stop();
    }

    public void ClientThreads(object tcpClient)
    {
        TcpClient clientSocket = (TcpClient)tcpClient;
        NetworkStream clientStream = clientSocket.GetStream();

        byte[] clientMessage = new byte[100];

        while (ServerOn)
        {
            clientStream.Read(clientMessage, 0, clientMessage.Length);
            string message = ByteArrayToStr(clientMessage);
            if (message.Contains("!chat"))
            {
                SendChatMessage(StrToByteArray(message.Substring(5) + Environment.NewLine));
            }
            else if (message.Contains("!start")) 
            {
                StartWebcam(((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address.ToString());
            }
            else if (message.Contains("!stop"))
            {
                StopWebcam(((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address.ToString());
            }
        }
        clientSocket.Close();
        connectedClients.Clear();
    }

    public void printToTextBox(string data)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new txtBoxDelegate(printToTextBox), data);
            return;
        }
        lstServerUpdates.Text += data + Environment.NewLine;
    }

    public void SendChatMessage(byte[] message)
    {
        foreach (TcpClient client in connectedClients)
        {
            NetworkStream stream = client.GetStream();
            stream.Write(message, 0, message.Length);
            printToTextBox(ByteArrayToStr(message));
        }
    }

    public void StartWebcam(string IPAddress)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new tcpCommand(StartWebcam), IPAddress);
            return;
        }

        //code to stop webcam for the specified client
        printToTextBox("Starting webcam for IP: " + IPAddress);
    }

    public void StopWebcam(string IPAddress)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new tcpCommand(StopWebcam), IPAddress);
            return;
        }

        //code to stop webcam for specified client
        printToTextBox("Stopping webcam for IP: " + IPAddress);
    }
}

【问题讨论】:

  • 代码。发表它。听起来像是您的 UI 代码有问题,而不是编码问题。
  • 还是不太清楚...这是什么,Windows 窗体? ASP.NET?您是看到 one 行上附加的所有内容,还是只看到一个换行符并期待两个?您确定文本框实际上配置为多行吗?您能否发布 确实 为您工作的代码,和/或我们可以查看实际输出吗?如果您使用Encoding.UTF8.GetBytes 创建一个字节数组会怎样? Environment.NewLine 甚至不在任何编码调用中,所以这真的不是问题。
  • 你说得对,我在一个单独的应用程序中对其进行了测试,并且它应该添加新行,让我再调试一下,如果我仍然无法理解,我会回复你出来。之前调试时我专注于错误的事情

标签: c# string sockets type-conversion


【解决方案1】:

我发送一个字节流

没错,TCP 是一个流。它不支持“数据包”之类的东西。就像一行文字。除了在客户端关闭连接之前接收所有内容之外,没有明显的方法可以将流转换为字节[]。这当然意味着您将显示所有内容,然后显示单个 Environment.NewLine。

重新考虑您的方法。就像实际发送数据中的行尾一样,因此您不必将它们添加到接收器中。通过首先发送 4 个字节对数据包长度进行编码来人工创建数据包是另一种方法。

【讨论】:

  • 这是有道理的!但是,我认为我的方法是完全错误的。我已将整个服务器附加到帖子中。您能否看一下并就如何使这项工作更好地提供任何建议? (这是一个学校项目,所以用的人不多)
  • 和我描述的完全一样。 SendChatMessage 尝试将数据包放入流中,而接收者无法将流转换回数据包。首先发送 byte[] 长度,以便接收者知道要读取多少字节。
  • 然后我用它来创建缓冲区大小?一旦我在服务器上获得了字节大小,那么我如何告诉它只读取那么多字节?
猜你喜欢
  • 1970-01-01
  • 2012-04-28
  • 2021-02-04
  • 2011-06-27
  • 2011-10-31
  • 1970-01-01
  • 2013-02-18
  • 2020-11-04
  • 2021-07-13
相关资源
最近更新 更多