简体   繁体   English

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

[英]C#: Unable to receive large data on TCP Server

I have created a TCP server. 我已经创建了一个TCP服务器。 I am facing one problem. 我面临一个问题。 my TCP Server is not receiving data larger than 30000 bytes. 我的TCP服务器没有收到大于30000字节的数据。

here is code to receive data 这是接收数据的代码

MAX_TCP_DATA = 64000 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();
                }
            }
        }

when i sent byte array of 40000. my TCP Server receives only 26280 bytes. 当我发送40000字节数组时,我的TCP服务器只收到26280字节。

Please tell me where is the problem in receiving. 请告诉我收到的问题在哪里。

The problem is that you can not receive packets of arbitrary size. 问题是您无法接收任意大小的数据包。 I see nothing in your code that indicates stream negotiation. 我的代码中没有看到任何表明流协商的内容。 TCP is a stream protocol, with the lower level using packets because it has to. TCP是一种流协议,较低级别使用数据包,因为它必须。 This means your sending data is split into arbitrary packets. 这意味着您的发送数据被分成任意数据包。 The reciving end packet size is pretty much random (hocw much is in the buffer) and may not even translate into a proper UTF8 complete strong at all. 恢复结束数据包的大小几乎是随机的(在缓冲区中非常多),甚至可能无法转换为完全强大的正确UTF8。

This: 这个:

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

Is not reading all data the client has sent, but all data the server has received. 不是读取客户端发送的所有数据,而是读取服务器收到的所有数据。 THis may not be complete. 这可能不完整。

You need to go into the documentation and acutally do your homework - ie read it. 你需要进入文档并实际完成你的作业 - 即阅读它。

It says: 它说:

The Read operation will read as much data as is available, up to the number of bytes specified by the size parameter. Read操作将读取尽可能多的数据,最多可达size参数指定的字节数。

Basically, at the moment there is no more data. 基本上,目前没有更多的数据。 It may be there a millisecond later. 它可能在一毫秒后出现。 This is why you need to know how much data to read before processing it - either with your own packet structure (having a length flag for example in the first two bytes), or by using CLRLF to indicate end of line - so when you get one you know you can process all bytes before. 这就是为什么你需要知道在处理之前要读取多少数据的原因 - 使用你自己的数据包结构(例如在前两个字节中有一个长度标志),或者使用CLRLF来指示行尾 - 所以当你得到一个你知道你可以处理所有字节之前。

The simplistic approach you have here simply will not work, as data transfer is not instant. 这里简单的方法根本不起作用,因为数据传输不是即时的。 The Read method will read whatever is cached at the receiver, and you assume this is basically all. Read方法将读取接收器上缓存的任何内容,并且您认为这基本上都是。

At the same time, the while is not necessary, except for handling clsoed sockets. 同时,除了处理插座外,其余时间不是必需的。 Again, the documentation helps: 同样,文档有助于:

If no data is available for reading, the NetworkStream.Read method will block until data is available. 如果没有可用于读取的数据,则NetworkStream.Read方法将阻塞,直到数据可用。

So, there is no way this returns 0 except the underlying socket was closed (and then it should throw an excception). 所以,除了底层套接字被关闭之外,它不会返回0(然后它应该抛出一个excception)。 Because it will wait until (some) data arrives. 因为它会等到(某些)数据到达。

Hint: Reading documentation is not a superflous thing. 提示:阅读文档不是一件容易的事。 In your case you assume a behavior that is clearly totally not there according to the documentation. 在你的情况下,根据文档,你假设一个显然完全不存在的行为。

It looks like you are trying to read all data together at once. 看起来您正试图一次读取所有数据。 NetworkStream is not worked as you expected. NetworkStream无法按预期工作。 You should read the stream in small chunks and copy to the recieved buffer if you want to get all the data you expected. 如果要获取所需的所有数据,则应以小块读取流并复制到接收的缓冲区。

In your case, you probably get 13720 bytes at first iteration and 26280 bytes at the second. 在您的情况下,您可能在第一次迭代时获得13720个字节,在第二次迭代时获得26280个字节。 As i stated before, it should be better to read in small chunks such as 64/256/1024 bytes etc. (especially in a slow network environment). 正如我之前所说,最好以64/256/1024字节等小块读取(特别是在慢速网络环境中)。

In your while loop, you are not guaranteed to get more data than 64k at a time. 在while循环中,不能保证一次获得的数据超过64k。 Are you receiving 26280 on the first read in the loop, or in total for all reads? 您是在循环中的第一次读取时收到26280,还是在所有读取中总共收到?

Typically you would need to read the whole stream first, then see how many bytes you have 通常,您需要先读取整个流,然后查看您拥有的字节数

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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM