如何调试“ Java NIO套接字通道发送和接收的字节大小不匹配”?

时间:2019-01-11 19:46:31

标签: java nio bytebuffer filechannel

请查看this question

这正是我正在寻找的东西,但我还没有达到。我正在通过socketChannel发送多个图像。我尝试将图像大小附加到(已清除的ByteBuffer)中,然后将图像数据附加到相同的缓冲区中(缓冲区大小足够大!)。

首先,在接收端,将通过ByteBuffer.read(...)读取图像大小,然后是ByteBuffer.flip()和ByteBuffer.getLong()(例如imageData = readBuffer.getLong())读取以下图像数据,我可以做ByteBuffer.comact()吗?我怎么知道要读取imageData的确切字节数?

否,我有以下内容: 在发送方:

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

在接收方:

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;

对于第一个图像,一切正常。发送方的文件计数器增加,发送方尝试发送下一张图像。 接收方现在得到:下一张图像的大小:例如。 1591323337052742968 怎么了?

1 个答案:

答案 0 :(得分:0)

尝试一下:
在客户端(发送)端

  1. 将图像的大小写成ByteBufferByteBuffer.putLong)。
  2. 将图像数据写入相同的ByteBufferByteBuffer.put(byte[]))。
  3. 致电ByteBuffer.flip
  4. ByteBuffer写入套接字通道。

在服务器(接收)端

  1. 从套接字通道读取到ByteBuffer
  2. 致电ByteBuffer.flip
  3. ByteBufferByteBuffer.getLong)中获取图像长度。
  4. 分配图像字节[](使用图像大小)。
  5. ByteBufferByteBuffer.get(byte[]))中读取图像。