首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TcpClient缺失数据

TcpClient缺失数据
EN

Stack Overflow用户
提问于 2013-07-25 15:48:12
回答 1查看 2.1K关注 0票数 0

我试图使用C#和System.Net.Sockets类为我的游戏编写网络部分。

  • 每个更新服务器都向客户端发送信息。
  • 所有信息都内置在2kb的数据包中,因此在1次更新中,可以发送1-2-3-5-10个数据包。
  • 客户端正在检查信息,如果信息具有正确的格式,那么就读取它。
  • 一切正常工作,直到服务器开始尝试发送太多的数据包。
  • 当发生这种情况时,客户端通常会接收带有错误数据的数据包,通常是20-50个数据包中的一个。
  • 例如,用于一个更新的1-2个数据包通常被接收到,3-10个数据包用于提供错误的数据流。
  • 如果我在一次启动几个客户端,那么应该从服务器获得相同的数据流--它们获得不同数量的成功和失败数据流。

我做错了什么,如何才能避免这种错误的数据流?

我是否只是在1毫秒内发送了太多的数据,并且需要在一段时间内发送?

这是发送的信息:

代码语言:javascript
复制
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);
        }
    }

这是接收到的信息:

代码语言:javascript
复制
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);
    }

它是主要的网络代码。

EN

回答 1

Stack Overflow用户

发布于 2013-07-25 16:41:57

我不知道在您收到数据之后如何处理这些数据,但是很可能您没有从连接中读取所有的数据。你有:

代码语言:javascript
复制
bytesRead = client.GetStream().EndRead(ar);

无法保证所读取的字节数是服务器发送的所有字节。例如,服务器可以发送2,048字节,但是当您调用Read时,只有1,024字节可用。其余的还在“中转”。正如NetworkStream.Read文档所说:

读取操作读取尽可能多的数据,最多读取由size参数指定的字节数。

你可能会收到部分数据包。如果您的DataReceived处理程序假定data缓冲区包含完整的数据包,那么您将遇到问题。

要从网络流可靠地读取数据,您需要知道应该读取多少数据,或者需要一个记录分隔符。有些东西必须确保,如果你期待一个完整的包,你得到一个完整的包之前,你试图处理它。您的代码只是检查是否bytesRead不是0。如果是别的什么,你就把它传下去。这将是一个问题,除非您的DataReceived处理程序知道如何缓冲部分数据包。

另外,您实际上不需要锁定网络流。除非您可以从同一流中读取多个线程。那将是灾难性的。把锁扔了。你不需要它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17862843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档