C#:无法在TCP服务器上接收大数据

时间:2010-10-18 06:14:48

标签: c# sockets tcp

我已经创建了一个TCP服务器。我面临一个问题。我的TCP服务器没有收到大于30000字节的数据。

这是接收数据的代码

MAX_TCP_DATA = 64000

private void Process()
        {
            if (client.Connected == true)
            {
                log.InfoFormat("Client connected :: {0}", client.Client.RemoteEndPoint);
                Byte[] bytes = new Byte[MAX_TCP_DATA];
                String data = null;
                NetworkStream stream = client.GetStream();

                int i;

                try
                {
                    // Loop to receive all the data sent by the client.
                    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        // bytes contains received data in byte[].
                        // Translate data bytes to a UTF-8 string.
                        byte[] receivedBuffer = new byte[i];
                        Array.Copy(bytes, receivedBuffer, i);

                        if (log.IsDebugEnabled)
                        {
                            data = System.Text.Encoding.UTF8.GetString(receivedBuffer);
                            log.InfoFormat("Received MSG ::: " + data);
                        }

                        CommEventArgs comEventArg = new CommEventArgs();
                        comEventArg.data = receivedBuffer;
                        IPEndPoint remoteIPEndPoint = (IPEndPoint)client.Client.RemoteEndPoint;
                        comEventArg.srcAddress = remoteIPEndPoint.Address.ToString();
                        comEventArg.srcPort = remoteIPEndPoint.Port;
                        comEventArg.length = i;
                        this.OnDataReceived(comEventArg);
                    }
                }
                catch (Exception ex)
                {
                    log.InfoFormat("Client disconnected : {0}", client.Client.RemoteEndPoint);
                }
                finally
                {
                   client.Close();
                }
            }
        }

当我发送40000字节数组时,我的TCP服务器只收到26280字节。

请告诉我收到的问题在哪里。

3 个答案:

答案 0 :(得分:5)

问题是您无法接收任意大小的数据包。我的代码中没有看到任何表明流协商的内容。 TCP是一种流协议,较低级别使用数据包,因为它必须。这意味着您的发送数据被分成任意数据包。回收结束数据包的大小非常随机(在缓冲区中非常多),甚至可能无法转换为完全强大的UTF8。

此:

  

while((i = stream.Read(bytes,0,   bytes.Length))!= 0)

不读取客户端发送的所有数据,而是读取服务器收到的所有数据。这可能不完整。

你需要进入文档并实际完成你的作业 - 即阅读它。

它说:

  

Read操作将读取尽可能多的内容   可用的数据,最多可达数字   由size指定的字节数   参数。

基本上,目前没有更多数据。它可能在一毫秒后出现。这就是为什么你需要知道在处理之前要读取多少数据的原因 - 使用你自己的数据包结构(例如在前两个字节中有一个长度标志),或者使用CLRLF来指示行尾 - 所以当你得到一个你知道你可以在之前处理所有字节。

这里简单的方法根本不起作用,因为数据传输不是即时的。 Read方法将读取接收器上缓存的任何内容,并且您认为这基本上都是。

同时,除了处理插座外,没有必要使用while。同样,文档有助于:

  

如果没有可供阅读的数据,   NetworkStream.Read方法会   阻止,直到数据可用。

所以,除了底层套接字被关闭(然后它应该抛出一个excception)之外,没有办法返回0。因为它会等到(某些)数据到达。

提示:阅读文档不是一件容易的事。在你的情况下,根据文档,你假设一个显然完全不存在的行为。

答案 1 :(得分:3)

看起来您正在尝试一次读取所有数据。 NetworkStream无法按预期工作。如果要获得预期的所有数据,应该以小块的形式读取流并复制到接收的缓冲区。

在您的情况下,您可能在第一次迭代时获得13720个字节,在第二次迭代时获得26280个字节。 正如我之前所说,最好以64/256/1024字节等小块读取(特别是在慢速网络环境中)。

答案 2 :(得分:1)

在while循环中,不能保证一次获得的数据超过64k。您是在第一次读取循环时收到26280,还是在所有读取中收到总数?

通常,您需要先读取整个流,然后查看您有多少字节

List<byte> allBytes = new List<byte>(MAX_TCP_DATA);
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
    allBytes.AddRange( allBytes.Take(i) );
}
Console.WriteLine(allBytes.Count);
string data = System.Text.Encoding.UTF8.GetString(allBytes.ToArray());