发送填充有特殊字符的字节数组



我正在WPF项目中制作一个具有客户端和服务器端的聊天程序。 我正在尝试从客户端向服务器发送用户名和消息,我使用此数据类。 使用英文字符没有问题,但是一旦我在用户名或消息中尝试使用特殊字符,一切都会陷入困境。可能是什么问题? 我尝试增加数组的大小,但这显然没有帮助 问题可视化

byte[] byteData = new byte[1024]
public Data(byte[] data)
{
//The first four bytes are for the Command
this.cmdCommand = (Command)BitConverter.ToInt32(data, 0);
//The next four store the length of the name
int nameLen = BitConverter.ToInt32(data, 4);
//The next four store the length of the message
int msgLen = BitConverter.ToInt32(data, 8);
//This check makes sure that strName has been passed in the array of bytes
if (nameLen > 0)
this.strName = Encoding.UTF8.GetString(data, 12, nameLen);
else
this.strName = null;
//This checks for a null message field
if (msgLen > 0)
this.strMessage = Encoding.UTF8.GetString(data, 12 + nameLen, msgLen);
else
this.strMessage = null;
}
//Converts the Data structure into an array of bytes
public byte[] ToByte()
{
List<byte> result = new List<byte>();
//First four are for the Command
result.AddRange(BitConverter.GetBytes((int)cmdCommand));
//Add the length of the name
if (strName != null)
result.AddRange(BitConverter.GetBytes(strName.Length));
else
result.AddRange(BitConverter.GetBytes(0));
//Length of the message
if (strMessage != null)
result.AddRange(BitConverter.GetBytes(strMessage.Length));
else
result.AddRange(BitConverter.GetBytes(0));
//Add the name
if (strName != null)
result.AddRange(Encoding.UTF8.GetBytes(strName));
//And, lastly we add the message text to our array of bytes
if (strMessage != null)
result.AddRange(Encoding.UTF8.GetBytes(strMessage));
return result.ToArray();
}
public string strName;      //Name by which the client logs into the room
public string strMessage;   //Message text
public Command cmdCommand;  //Command type (login, logout, send message, etcetera)
}

如果没有一个好的最小、可重现的示例来可靠地重现问题,就不可能确定。但根据您发布的代码,您似乎误解了文本(string(值与发送数据长度之间的关系。

首先,确保您了解TCP(如果这是您正在使用的协议......因为您正在发送密码,希望它是,并且您已将套接字包装在SSL流中(没有内置的消息框架。这完全取决于你来实现这一点。您在数据中包含长度的事实表明您已经理解了这一点,但我想强调一下以防万一。

其次,您发送的长度是string值的字符长度。这仅与string仅包含 ASCII 字符时发送的字节数相同。UTF8 和 ASCII 编码的前 128 个字符重叠,这些字符在两个编码中都具有单字节值...对于所有其他字符,UTF8 使用两个或多个字节。这意味着,当您使用"特殊字符">时,您发送的长度值与您发送的数据的实际长度(以字节为单位(不同。

最有可能的是,您需要修复发送代码,使其看起来更像这样:

public byte[] ToByte()
{
List<byte> result = new List<byte>();
byte[] nameBytes = strName != null ? Encoding.UTF8.GetBytes(strName) : null,
messageBytes = strMessage != null ? Encoding.UTF8.GetBytes(strMessage) : null;
//First four are for the Command
result.AddRange(BitConverter.GetBytes((int)cmdCommand));
//Add the length of the name
if (strName != null)
result.AddRange(BitConverter.GetBytes(nameBytes.Length));
else
result.AddRange(BitConverter.GetBytes(0));
//Length of the message
if (strMessage != null)
result.AddRange(BitConverter.GetBytes(messageBytes.Length));
else
result.AddRange(BitConverter.GetBytes(0));
//Add the name
if (strName != null)
result.AddRange(nameBytes);
//And, lastly we add the message text to our array of bytes
if (strMessage != null)
result.AddRange(messageBytes);
return result.ToArray();
}

这将在发送数据长度之前获取编码的文本,然后使用文本在消息中实际编码的文本长度,而不是文本的字符长度(与数据出现在网络上时的长度没有直接关系(。

请注意,您需要仔细检查接收代码,以确保它正确解码了这种新格式。它可能已经是了,但你没有发布它,所以我不能说它是否发布。

最新更新