我正在尝试使用System.Net.Sockets
和TcpClient
类在C#中为我的游戏编写网络部分。
我做错了什么,如何规避错误的数据流呢?
我只是在1毫秒内发送过多数据,需要随时间发送数据吗?
这是发送信息:
TcpClient client;
public void SendData(byte[] b)
{
//Try to send the data. If an exception is thrown, disconnect the client
try
{
lock (client.GetStream())
{
client.GetStream().BeginWrite(b, 0, b.Length, null, null);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
这是接收信息:
byte[] readBuffer;
int byfferSize = 2048;
private void StartListening()
{
client.GetStream().BeginRead(readBuffer, 0, bufferSize, StreamReceived, null);
}
private void StreamReceived(IAsyncResult ar)
{
int bytesRead = 0;
try
{
lock (client.GetStream())
{
bytesRead = client.GetStream().EndRead(ar); // просмотр длины сообщения
}
}
catch (Exception ex)
{ MessageBox.Show(ex.Message); }
//An error happened that created bad data
if (bytesRead == 0)
{
Disconnect();
return;
}
//Create the byte array with the number of bytes read
byte[] data = new byte[bytesRead];
//Populate the array
for (int i = 0; i < bytesRead; i++)
data[i] = readBuffer[i];
//Listen for new data
StartListening();
//Call all delegates
if (DataReceived != null)
DataReceived(this, data);
}
这是主要的网络代码。
答案 0 :(得分:2)
收到数据后,我不知道您对数据做了什么,但很可能您没有从连接中读取所有数据。你有:
bytesRead = client.GetStream().EndRead(ar);
无法保证您读取的字节数是服务器发送的所有字节数。例如,服务器可能发送了2,048个字节,但是当您调用Read
时,只有1,024个字节可用。其余的人仍然“在途中”。正如documentation for NetworkStream.Read所说:
Read操作读取尽可能多的数据,最多为size参数
指定的字节数
您可能会获得部分数据包。如果您的DataReceived
处理程序假定data
缓冲区包含完整的数据包,那么您将遇到问题。
要从网络流中可靠地读取数据,您需要知道应该读取多少数据,或者需要一个记录分隔符。如果你想要一个完整的数据包,那么你必须确保在尝试处理它之前获取一个完整的数据包。您的代码只是检查bytesRead
是否不是0.如果是其他任何内容,您只需将其传递。除非你的DataReceived
处理程序知道如何缓冲部分数据包,否则这将成为一个问题。
另一方面,您确实不需要锁定网络流。除非您可以从同一个流中读取多个线程。这将是灾难性的。抛开锁。你不需要它。