简体   繁体   English

如何调试“Java NIO Socket Channel 发送和接收字节大小不匹配”?

[英]How to debug "Java NIO Socket Channel mismatch in size of sent and received bytes"?

Please look at this question .请看这个问题

This is exact what I'm looking for but I didn't reach it yet.这正是我正在寻找的,但我还没有达到。 I'm sending multiple of images over a socketChannel.我正在通过 socketChannel 发送多个图像。 I try to attach the image size into a (cleared ByteBuffer) and attach then the image data into the same buffer (the buffer size is big enough!).我尝试将图像大小附加到(已清除的 ByteBuffer)中,然后将图像数据附加到同一个缓冲区中(缓冲区大小足够大!)。

On the receiving side first the image size will be read by ByteBuffer.read(...), then ByteBuffer.flip() and ByteBuffer.getLong() (eg. imageData = readBuffer.getLong()) To read the following image data, have I do ByteBuffer.comact()?在接收端首先会通过 ByteBuffer.read(...) 读取图片大小,然后通过 ByteBuffer.flip() 和 ByteBuffer.getLong() (eg. imageData = readBuffer.getLong()) 来读取下面的图片数据,我做了 ByteBuffer.comact() 吗? How do I realize that exact the number of bytes of imageData will be read?我如何知道将读取确切的 imageData 字节数?

No I have the following: On the sender-side:不,我有以下内容: 在发送方:

socketChannelEntity.getWriteBuffer().clear();
            if(socketChannelEntity.getFileToProcessCounter() < fileList.size()){
                this.fileName = fileList.get(socketChannelEntity.getFileToProcessCounter()).toString();
                System.out.println("NIO_CLIENT: " + socketChannelEntity.getEntityName() + ": Send next image: " + fileName);
            } else {
                System.out.println("NIO_CLIENT: No more images to send.");
                socketChannelEntity.setSendReceiveStatus(SendReceiveStatusClient.DONE);
                socketChannel.register(this.selector, SelectionKey.OP_READ, socketChannelEntity);
                return;
            }
            Path path = Paths.get(fileName);
            long fileSize = Files.size(path);
            System.out.println(fileName + " size: " + fileSize);
            socketChannelEntity.getWriteBuffer().putLong(fileSize);
            try{
                FileChannel fileChannel = FileChannel.open(path);
                int numRead = 0;
                int counter = 0;
                while((numRead = fileChannel.read(socketChannelEntity.getWriteBuffer())) > 0){
                    counter += numRead;
                    socketChannelEntity.getWriteBuffer().flip();
                    do {
                        numRead -= socketChannel.write(socketChannelEntity.getWriteBuffer());
//                      socketChannelEntity.getWriteBuffer().clear();
                    } while (numRead > 0);
                }
                fileChannel.close();
                System.out.println("NIO_CLIENT: " + socketChannelEntity.getEntityName() + ": Image " + fileName + " sent: " + counter + " bytes long");
                socketChannelEntity.setCheckSum(fileSize);
                socketChannelEntity.setSendReceiveStatus(SendReceiveStatusClient.RECEIVE_CHECKSUM_IMAGE);
            } catch(IOException e) {
                e.printStackTrace();
            }

On the receiver side:在接收端:

if(socketChannel.socket().getLocalPort() == 10000){
                outputFile =  Config.HOME_PATH_SERVER_1 + "receivedImage" + fileNameCounter + ".jpg";
            } else if(socketChannel.socket().getLocalPort() == 10001){
                outputFile =  Config.HOME_PATH_SERVER_2 + "receivedImage" + fileNameCounter + ".jpg";
            }
            Path path = Paths.get(outputFile);
            FileChannel fileChannel = FileChannel.open(path,
                    EnumSet.of(StandardOpenOption.CREATE,
                            StandardOpenOption.TRUNCATE_EXISTING,
                            StandardOpenOption.WRITE));
            int numRead = 0;
            int counter = 0;
            readBuffer.clear();
            socketChannel.read(readBuffer);
            readBuffer.flip();
            checkSum = readBuffer.getLong();
            System.out.println("Server erwartet ein Bild der Groesse: " + checkSum);
            readBuffer.limit((int)checkSum+8);
            fileChannel.write(readBuffer);
            fileChannel.close();
            if(readBuffer.hasRemaining()){
                System.out.println("Ist noch was im ReadBuffer!");
            }
            prepareWriteBuffer(checkSum);
            System.out.println("NIO_SERVER: Received image.");
            sendReceiveStatus = SendReceiveStatusServer.SEND_CHECKSUM_IMAGE;

For the first image everything works fine.对于第一张图片,一切正常。 The filecounter on the sender side increments and the sender tries to send the next image.发送方的文件计数器递增,发送方尝试发送下一个图像。 The receiver side gets now: size for the next image: eg.接收方现在得到:下一个图像的大小:例如。 1591323337052742968 What is wrong? 1591323337052742968 怎么了?

Try this:尝试这个:
On the Client (sending) Side在客户端(发送)端

  1. Write the size of the image to a ByteBuffer ( ByteBuffer.putLong ).将图像的大小写入ByteBuffer ( ByteBuffer.putLong )。
  2. Write the image data to the same ByteBuffer ( ByteBuffer.put(byte[]) ).将图像数据写入同一个ByteBuffer ( ByteBuffer.put(byte[]) )。
  3. Call ByteBuffer.flip .调用ByteBuffer.flip
  4. Write the ByteBuffer to the socket channel.ByteBuffer写入套接字通道。

On the Server (receiving) Side在服务器(接收)端

  1. Read from the socket channel into a ByteBuffer .从套接字通道读取到ByteBuffer
  2. Call ByteBuffer.flip .调用ByteBuffer.flip
  3. Get the image length out of the ByteBuffer ( ByteBuffer.getLong ).ByteBuffer ( ByteBuffer.getLong ) 中获取图像长度。
  4. Allocate the image byte[] (using the image size).分配图像字节[](使用图像大小)。
  5. Read the image out of the ByteBuffer ( ByteBuffer.get(byte[]) ).ByteBuffer ( ByteBuffer.get(byte[]) ) 中读取图像。

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

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