【问题标题】:Simple Java network IO is not working for large data简单的 Java 网络 IO 不适用于大数据
【发布时间】:2014-06-09 09:13:44
【问题描述】:

我遇到了一个奇怪的问题,它没有出现在 MACOS 上,而只出现在 linux 上...... 当我在 linux 中运行以下代码时,有时会收到不一致的消息。 该代码只是创建了两个线程,其中一个向另一个发送大量全为 1 的字节数组,另一个线程只是检查所有内容是否为 1。它偶尔会发生(似乎取决于 n..)它收到 0。

有人可以帮帮我吗?

    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;

    public class TestIO {
        static final int n = 500000;
        final static byte d  = 10;

        static class SenderRunnable implements Runnable {
            SenderRunnable () {}
            private ServerSocket sock;
            protected OutputStream os;

            public void run() {
                try {
                    sock = new ServerSocket(12345);            // create socket and bind to port
                    Socket clientSock = sock.accept();                   // wait for client to connect
                    os = clientSock.getOutputStream();  

                    byte[] a = new byte[10];
                    for(int i = 0; i < 10; ++i)
                        a[i] = d;

                    for (int i = 0; i < n; i++) {
                        os.write(a);
                    }
                    os.flush();

                    sock.close(); 
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }

        static class ReceiverRunnable implements Runnable {
            ReceiverRunnable () {}
            private Socket sock;
            public InputStream is;
            public void run() {
                try {
                    sock = new java.net.Socket("localhost", 12345);          // create socket and connect
                    is = sock.getInputStream();

                    for (int i = 0; i < n; i++) {
                        byte[] temp = new byte[10];
                        is.read(temp);
                        for(int j = 0; j < 10; ++j)
                            if(temp[j] != d){
                                System.out.println("weird!"+" "+i+" "+j+" "+temp[j]);
                            }
                    }
                    sock.close(); 
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }


        public static void test1Case() throws Exception {
            SenderRunnable sender = new SenderRunnable();
            ReceiverRunnable receiver = new ReceiverRunnable();
            Thread tSnd = new Thread(sender);
            Thread tRcv = new Thread(receiver);
            tSnd.start(); 
            tRcv.start(); 
            tSnd.join();
            tRcv.join();
        }

        public static void main(String[] args)throws Exception {
            test1Case();
            test1Case();
            test1Case();
            test1Case();
            test1Case();
            test1Case();
            test1Case();
            test1Case();
        }
    }

谢谢!我将部分代码更改为以下代码,它现在可以工作了。

    for (int i = 0; i < n; i++) {
        byte[] temp = new byte[10];
        int remain = 10;
        remain -= is.read(temp);
        while(0 != remain)
        {
            remain -= is.read(temp, 10-remain, remain);
        }
        for(int j = 0; j < 10; ++j)
            if(temp[j] != d){
                System.out.println("weird!"+" "+i+" "+j+" "+temp[j]);
            }
    }

【问题讨论】:

    标签: java io network-programming


    【解决方案1】:

    您的错误在于读者方面。 方法read() 不保证填充您的数组。它只接收已经可用的字节并返回已经获得的字节数。所以你必须在循环中读取字节,直到 read 返回 -1。

    【讨论】:

    • 更好的是,使用 DataInputStream.readFully(), 已经可以做到这一点。
    • 看看DataInputStream.readFully()的实现:它实现了我描述的模式。因此,使用它是可以的。您还可以使用来自 apache IOUtils 的各种实用程序
    【解决方案2】:

    你应该检查调用InputStream.read()http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read(byte[])时实际读取的字节数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-20
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 2013-09-24
      • 1970-01-01
      相关资源
      最近更新 更多