【问题标题】:read and write method for large data in socket communication does not work reliablysocket通信中大数据的读写方法不可靠
【发布时间】:2009-04-23 04:59:23
【问题描述】:

我为服务器客户端通信创建了一个套接字编程。 我正在使用read(byte[])DataInputStream 读取数据,同时使用write(byte[])DataOutputStream 写入数据。

每当我发送少量数据时,我的程序都可以正常工作。 但是如果我发送 20000 个字符的数据并发送 10 次,那么我可以完美接收数据 8 次,但不能接收 2 次。

那么我可以在套接字编程中使用读写可靠地发送和接收数据吗?

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    我的猜测是您正在向read() 发出一次调用,并假设它将返回您要求的所有数据。流通常不会那样工作。它会阻塞直到 一些 数据可用,但它不会等到它有足够的数据来填充数组。

    通常这意味着循环。例如:

    byte[] data = new byte[expectedSize];
    int totalRead = 0;
    while (totalRead < expectedSize)
    {
        int read = stream.read(data, totalRead, expectedSize-totalRead);
        if (read == -1)
        {
            throw new IOException("Not enough data in stream");
        }
        totalRead += read;
    }
    

    如果您一开始不知道预期的字节数,您可能仍希望循环,但这一次直到read() 返回-1。使用缓冲区(例如 8K)读取和写入 ByteArrayOutputStream。读完之后,就可以从ByteArrayOutputStream 中取出数据作为字节数组。

    【讨论】:

      【解决方案2】:

      绝对 -- TCP 套接字是一个可靠的网络协议,只要 API 使用得当。

      您确实需要检查每次调用 read() 时收到的字节数。

      套接字将任意决定您有足够的数据并将其传递回 hte 读取调用 - 数量可能取决于许多因素(缓冲区大小、内存可用性、网络响应时间等),其中大多数是不可预测的。对于较小的缓冲区,您通常会获得所需的字节数,但是对于较大的缓冲区大小,read() 通常会返回比您要求的更少的数据——您需要检查读取的字节数并重复 read 调用剩余字节数。

      您的网络基础设施(路由器、防火墙等)中的某些东西也可能配置错误并截断大数据包。

      【讨论】:

        【解决方案3】:

        你的问题是,在服务器线程中,你必须调用 outputstream.flush(),来指定缓冲的数据应该发送到通信的另一端

        【讨论】:

        • 我使用了flush()。但它不能正常工作,但如果我把时间放在 dalay 就可以了。
        • 那么如何通过 tcp java 发送大文件
        猜你喜欢
        • 1970-01-01
        • 2012-05-29
        • 2013-08-26
        • 1970-01-01
        • 2016-11-01
        • 2015-12-18
        • 2020-01-29
        • 1970-01-01
        • 2012-08-18
        相关资源
        最近更新 更多