我已经按照使用ASCII编码的聊天教程发送/接收消息,并且它用于连续读取4096个字节以在聊天客户端上写入.但现在我已将编码更改为unicode,我知道Unicode每个字符使用更多字节.
我的代码如下:
taskOpenEndpoint = Task.Factory.StartNew(() =>
{
while (true)
{
serverStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead = 0;
try
{
bytesRead = serverStream.Read(message, 0, 4096);
}
catch (Exception ex)
{
if(flag_chiusura == false)
MessageBox.Show(ex.Message);
return;
}
UnicodeEncoding encoder = new UnicodeEncoding();
AddMessage(encoder.GetString(message, 0, bytesRead));
Thread.Sleep(500);
}
});
Run Code Online (Sandbox Code Playgroud)
我是否应该更改读取的字节数,现在我正在使用Unicode编码?
切换到Unicode肯定会对此代码产生影响.它是有缺陷的代码,它假定您将从套接字读取数据的"数据包".仅当您使用UDP套接字时才会出现这种情况,TCP套接字会实现流.从套接字读取的字节数完全不可预测,并且与网络连接另一端传输的字节数不匹配.
你的Thread.Sleep()调用是一种解决方法.然而,这是一种非常邪恶的修复方式.例如,它被放置在错误的位置,在您阅读之后而不是在您阅读之前睡觉.更糟糕的是,它不能保证错误实际上是固定的,它的另一端的应用程序也会受到延迟,例如当机器负载很重时,你仍然不会读取"数据包".这种情况几乎不会经常发生,无法调试问题.而这在千里之外的机器上是个问题,当然这完全不可能.
因此,使用Unicode会增加应用崩溃的几率.当要求解码部分字节序列时,编码器将抛出.
你需要修复bug.删除Thread.Sleep()调用.首先通过传输数据包中的字节数来转换数据包流中的TCP流.接收器现在可以读取长度并知道循环的频率,重复调用Read()直到它收到所有字节.在此之后,解码当然不会造成任何麻烦.