c# - 为什么在字节数组和字符串之间转换时,Environment.NewLine 不起作用

标签 c# string sockets type-conversion

我正在使用 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 编码=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);
    }
}

最佳答案

I send a stream of bytes

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

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

关于c# - 为什么在字节数组和字符串之间转换时,Environment.NewLine 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13204815/

相关文章:

c# - Windows Identity Foundation 中的 TrustedIssuers

python - 从给定列表生成所有可能的 k-mers(字符串组合)

python - 阻塞套接字什么时候会超时?

linux - __NR_accept 的定义在哪里?

c# - 使用 GroupBy 和 Count 在 Linq 中产生不同的结果

c# - 具有多个 OR 条件的 Linq to Entity Join 表

c# - 如果文件格式与列表中的任何内容匹配,则改进 C# 中的测试方法

javascript - 在javascript中使用变量的值作为变量

java - 删除成对的括号({},(),[])和其中的文本,并用Java中字符串中的空格替换剩余的不成对的

php - SQL 数据库和 MQTT(Mosquitto 或 RSMB)