Java DatagramChannel挂起

时间:2014-09-08 11:52:35

标签: java udp nio channel bytebuffer

我正在开始一些Java NIO编程,并且正在构建两个单独的Java程序。一种是创建一些随机数据通过UDP发送,另一种是接收这些数据,并可能对其执行一些处理。

在每个类中,我已经定义了要发送/接收的数据的SIZE,以及一次(每个数据包)以8个字节发送或接收的字节数。当我有一个1024字节的SIZE时,我可以打开接收器(默认等待一些数据包到达),之后我打开发送数据包的发送器,接收器正确接收这些数据包并终止所有数据包收到数据包。然后我尝试将SIZE设置为10兆字节。我启动接收器,然后启动发送器。发件人似乎工作正常并在几秒钟后终止。接收器开始工作并继续读取多个数据包(我在代码周围放了一些printlns)。但是,在此过程中的某个地方,接收器似乎挂起并停止接收更多数据包。我不知道挂起的位置,只是在缓冲区被清除以进行新读取之后才会发生。

也许我错误地使用了这个库。非常感谢任何帮助。

发件人类称为UDPSender,如下所示:

    public class UDPSender {

    public static void main(String[] args) {
        try {
            // Generate some data to send
            int SIZE=1024*1024*10;
            int bufferBytes = 8;

            byte[] b = new byte[SIZE];
            new Random().nextBytes(b);
            String value = new String(b);
            //System.out.println(value);

            // Create Datagram channel for sending UDP packets
            DatagramChannel sendingChannel = DatagramChannel.open();
            // Bind the channel to a specific sending socket address and port
            InetSocketAddress sendSocket = new InetSocketAddress("127.0.0.1", 9999);
            sendingChannel.socket().bind(sendSocket);

            //Target socket address
            InetSocketAddress targetSocket = new InetSocketAddress("127.0.0.1", 8888);
            //loop to send bufferBytes bytes at a time
            int location = 0;
            int bytesSent = 0;
            long startTime=0; long endTime=0; long elapsedTime=0;  // for speed benchmarking
            startTime = System.nanoTime();
            for (int i = 1; i <= SIZE / bufferBytes; i++) {
                //System.out.println(i);
                ByteBuffer buf = ByteBuffer.allocate(bufferBytes);
                buf.clear();
                buf.put(Arrays.copyOfRange(b, location, location + bufferBytes));
                location = location + bufferBytes;
                buf.flip();
                bytesSent = bytesSent + sendingChannel.send(buf, targetSocket);
            }
            endTime = System.nanoTime();
            elapsedTime = endTime - startTime;
            double elapsedTimeMs = elapsedTime / 1000000.0;
            System.out.println("Elapsed:" + elapsedTimeMs + " msec");
        } catch (IOException ex) {
            Logger.getLogger(UDPSender.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

第二个类叫做UDPReceiver,如下所示:

    public class UDPReceiver {
    public static void main(String[] args) {
        try {
            int SIZE=1024*1024*10;
            int bufferBytes = 8;
            int packet_max = SIZE/bufferBytes;

            // Create Datagram channel for receiving UDP packets
            DatagramChannel receivingChannel = DatagramChannel.open();
            // Bind the channel to a specific receiving socket address and port
            InetSocketAddress receiveSocket = new InetSocketAddress("127.0.0.1",8888);
            receivingChannel.socket().bind(receiveSocket);
            // Set up address of send
            InetSocketAddress sendSocket = new InetSocketAddress("127.0.0.1",9999);
            // Connect our receiving socket to their sending socket address
            receivingChannel.connect(sendSocket);

            long startTime=0; long endTime=0; long elapsedTime=0;  // for speed benchmarking
            byte[] b = new byte[SIZE]; //receiving storage
            int packets=0; int location=0; int bytesCount; //byte[] indexes
            boolean clockStart=false;


            //try indirect ByteBuffer
            System.out.println("Indirect ByteBuffer()");
            ByteBuffer buf = ByteBuffer.allocate(bufferBytes);
            packets=0; location=0; bytesCount = 0; clockStart=false;
            while ((bytesCount = receivingChannel.read(buf)) > 0) { // Read data from file into ByteBuffer
                System.out.println(".");
                if(clockStart==false){
                    startTime = System.nanoTime();
                    clockStart=true;
                }
                // flip the buffer which set the limit to current position, and position to 0.
                buf.flip(); System.out.println("..");
                System.arraycopy(buf.array(), 0, b, location, buf.capacity()); System.out.println("..."); // Write data from ByteBuffer to bytearray
                location=location+bufferBytes; System.out.println("....");
                buf.clear();  System.out.println(".....");    // For the next read
                packets = packets+1; System.out.println("......");
                if(packets==packet_max){
                    System.out.println(".......");
                    System.out.println(packets);
                    break;
                }
            }
            endTime = System.nanoTime();
            elapsedTime = endTime - startTime;
            System.out.println("ByteBuffer() Elapsed Time is " + (elapsedTime / 1000000.0) + " msec");

        } catch (IOException ex) {
            System.out.println(ex.toString());
            //Logger.getLogger(UDPReceiver.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

它没有挂起&#39;它阻止,它就是这样做的,因为你试图读取特定数量的数据包而不考虑这个事实UDP是不可靠的。当您丢失数据包时,您的发送方和接收方都不会知道,因此您的发送方不会重新发送,并且您的接收方一直在尝试读取所有数据包,这些数据包永远不会到达