【问题标题】:Sending a string containing special characters through a TcpClient (byte[])通过 TcpClient (byte[]) 发送包含特殊字符的字符串
【发布时间】:2013-02-11 12:01:01
【问题描述】:

我正在尝试通过 TcpClient (byte[]) 发送包含特殊字符的字符串。这是一个例子:

  • 客户在文本框中输入“amé”
  • 客户端使用某种编码将字符串转换为字节[](我已经尝试了所有预定义的以及像“iso-8859-1”这样的一些)
  • 客户端通过 TCP 发送字节[]
  • 服务器接收并输出使用相同编码重新转换的字符串(到列表框)

编辑:

我忘了说结果字符串是“am?”。

Edit-2(根据要求,这里有一些代码):

@DJKRAZE 这里有一些代码:

byte[] buffer = Encoding.ASCII.GetBytes("amé");
(TcpClient)server.Client.Send(buffer);

在服务器端:

byte[] buffer = new byte[1024];
Client.Recieve(buffer);
string message = Encoding.ASCII.GetString(buffer);
ListBox1.Items.Add(message);

出现在列表框中的字符串是“am?”

=== 解决方案===

Encoding encoding = Encoding.GetEncoding("iso-8859-1");
byte[] message = encoding.GetBytes("babé");

更新:

简单地使用Encoding.Utf8.GetBytes("ééé"); 就像一个魅力。

【问题讨论】:

  • Philippe 你有现有的代码吗?为什么人们在这里在线提问并期望我们知道他们在说什么..?我们看不到您在做什么,也不知道您的代码是什么样的。所以发布您正在使用的内容...
  • @DJKRAZE 这里有一段代码: byte[] buffer = Encoding.ASCII.GetBytes("amé"); (TcpClient)server.Client.Send(buffer);在服务器端: byte[] buffer = new byte[1024]; Client.Recieve(缓冲区);字符串消息 = Encoding.ASCII.GetString(buffer); ListBox1.Items.Add(消息);出现在列表框中的字符串是“am?”
  • ASCII 在这里不行——它不支持重音字符。请改用 UTF-8。
  • @500-InternalServerError 尝试了所有预定义的,包括 utf-8.. :S
  • 如果去掉中间人(套接字连接),它是否适用于 UTF-8?

标签: c# .net encoding tcp special-characters


【解决方案1】:

回答我认为的问题永远不会太晚,希望有人能在这里找到答案。

C# 使用 16 位字符,而 ASCII 将它们截断为 8 位,以适应一个字节。经过一番研究,我发现 UTF-8 是特殊字符的最佳编码。

//data to send via TCP or any stream/file
byte[] string_to_send = UTF8Encoding.UTF8.GetBytes("amé");

//when receiving, pass the array in this to get the string back
string received_string = UTF8Encoding.UTF8.GetString(message_to_send);

【讨论】:

  • 您说here 已经尝试过,但没有成功。发生了什么变化?
  • 没有。 C# 的 char 数据类型包含一个 UTF-16 代码单元,其中一个或两个编码一个 Unicode 代码点。 UTF-8 将 Unicode 代码点编码为 1 到 4 个字节。只要您在两边都使用相同的编码,并且编码不会因为无法表示您需要的字符而导致您丢失数据,那么您使用哪种编码并不重要。如果不能,GetBytes() 将采取一些措施。标准动作是替换“?”;抛出异常也很常见;截断并不常见,但如果你想导致数据损坏,你可以这样编码。
  • Scott,很明显我的代码还有其他问题。 UTF-8 编码在双方使用时都能完美运行。我更新了问题,以免人们误以为我说 utf-8 不起作用。
  • Tom,我的意思是,不管 C# 存储 char 本身,它是 2 个字节,因此,ascii 对像“é”这样的特殊字符没有帮助
  • @PhilippeParé 和 Tom 所说的是 C# 在内部使用 UTF-16,其大小可能为 2 或 4 个字节。例如U+1D11E (MUSICAL SYMBOL G CLEF) 是可表示的,但它是内存中的四个字节D8 34 DD 1E
【解决方案2】:

您的问题似乎是 Encoding.ASCII.GetBytes("amé");Encoding.ASCII.GetString(buffer); 调用,正如他的 cmets 中的“500 - 内部服务器错误”所暗示的那样。

é 字符是一个多字节字符,它以 UTF-8 编码,字节序列为C3 A9。当您使用Encoding.ASCII 类进行编码和解码时,é 字符将转换为问号,因为它没有直接的 ASCII 编码。这适用于任何在 ASCII 中没有直接编码的字符。

将您的代码更改为使用Encoding.UTF8.GetBytes()Encoding.UTF8.GetString(),它应该适合您。

【讨论】:

    【解决方案3】:

    我不清楚您的问题和错误,但使用 Base64String 可能会解决问题
    像这样的

    static public string EncodeTo64(string toEncode)
        {
          byte[] toEncodeAsBytes
                = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
          string returnValue
                = System.Convert.ToBase64String(toEncodeAsBytes);
          return returnValue;
        }
    
    static public string DecodeFrom64(string encodedData)
        {
          byte[] encodedDataAsBytes
              = System.Convert.FromBase64String(encodedData);
          string returnValue =
             System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
          return returnValue;
        }
    

    【讨论】:

    • 试过实现这个,不工作...我收到错误说字符串不在base64中...
    • 好的!找到了解决这个巨大问题的方法。我现在使用“iso-8859-1”编码。这里有一些代码供任何对未来感兴趣的人使用。编码编码 = Encoding.GetEncoding("iso-8859-1"); byte[] message = encoding.GetBytes("babé");结果服务器端:“宝贝”!无论如何感谢所有的答案:)
    猜你喜欢
    • 2020-12-25
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 2014-03-30
    相关资源
    最近更新 更多