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

C#:无法在TCP服务器上接收大数据,c#,sockets,tcp,C#,Sockets,Tcp,我已经创建了一个TCP服务器。我面临一个问题。我的TCP服务器接收的数据不超过30000字节 下面是接收数据的代码 最大TCP\u数据=64000 private void Process() { if (client.Connected == true) { log.InfoFormat("Client connected :: {0}", client.Client.RemoteEndPoint)

我已经创建了一个TCP服务器。我面临一个问题。我的TCP服务器接收的数据不超过30000字节

下面是接收数据的代码

最大TCP\u数据=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字节


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

问题是您无法接收任意大小的数据包。我在代码中没有看到任何表示流协商的内容。TCP是一种流协议,较低级别使用数据包,因为它必须这样做。这意味着您发送的数据被拆分为任意数据包。接收端数据包的大小几乎是随机的(hocw在缓冲区中),甚至可能根本无法转换为正确的UTF8完全强

这:

而((i=stream.Read)(字节,0, 字节(长度)!=0)

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

你需要仔细阅读文档,并认真做你的家庭作业,即阅读它

它说:

读取操作将读取同样多的数据 数据可用,最多为 由大小指定的字节数 参数

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

由于数据传输不是即时的,您在这里使用的过于简单的方法根本不起作用。Read方法将读取在接收方缓存的任何内容,您假设这基本上就是全部

同时,除了处理clsoed套接字之外,不需要while。同样,文档有助于:

如果没有可读取的数据, NetworkStream.Read方法将 阻止,直到数据可用

因此,除了底层套接字被关闭(然后它应该抛出一个Exception)之外,它不可能返回0。因为它将等待(某些)数据到达


提示:阅读文档不是一件超级棒的事情。在您的情况下,根据文档,您假设的行为显然完全不存在。

在while循环中,您不能保证一次获得超过64k的数据。您是在循环中第一次读取时收到26280,还是在所有读取时总共收到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());
List allBytes=新列表(最大TCP数据);
int i;
而((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());

看起来您正试图同时读取所有数据。NetworkStream未按预期工作。如果您想要获得所有您期望的数据,您应该以小块的形式读取流并复制到接收的缓冲区

在您的例子中,第一次迭代可能得到13720字节,第二次迭代可能得到26280字节。
如前所述,最好是以小数据块(如64/256/1024字节等)进行读取(尤其是在慢速网络环境中)。

我建议在处理数据包级代码时使用某种网络调试(嗅探)软件。您确定这里没有任何异常吗?此外,我没有看到任何接收数据的连接,您是否计算总数?数据可以很容易地分块到达,这一点也不例外。如果我将断点放在字节[]receivedBuffer=新字节[i];它命中两次而不是一次,所以如果您记录ex变量以登录catch?那么,使用MSDN文档化就没有问题了。这真的是你所需要的——至少这是我学会如何编程的方式。我通过读取小块,然后将所有块组合到一个大字节数组来解决这个问题。strea.Read()方法调用多次,具体取决于网络流上的可用数据。您还可以使用networkStream.DataAvailable标志检查正在进行的数据传输会话中是否有更多数据。