-3

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. 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!).

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()? How do I realize that exact the number of bytes of imageData will be read?

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?

AppFell
  • 1
  • 1
  • 2
    Show, don't tell. We need to see your code, not a description of it. To attach it to your question, just copy-paste it into the body of your question. Then highlight the code you've pasted in and click the `{}` button at the top of the editing window to format it as a code block. – mypetlion Jan 11 '19 at 20:01
  • 1
    Beyond that... Please try to phrase your question in the form of a question. Whether you have to call `ByteBuffer#compact` will depend on what you are trying to achieve. – mypetlion Jan 11 '19 at 20:02

1 Answers1

0

Try this:
On the Client (sending) Side

  1. Write the size of the image to a ByteBuffer (ByteBuffer.putLong).
  2. Write the image data to the same ByteBuffer (ByteBuffer.put(byte[])).
  3. Call ByteBuffer.flip.
  4. Write the ByteBuffer to the socket channel.

On the Server (receiving) Side

  1. Read from the socket channel into a ByteBuffer.
  2. Call ByteBuffer.flip.
  3. Get the image length out of the ByteBuffer (ByteBuffer.getLong).
  4. Allocate the image byte[] (using the image size).
  5. Read the image out of the ByteBuffer (ByteBuffer.get(byte[])).
DwB
  • 37,124
  • 11
  • 56
  • 82
  • Great thaks for it! I'll try to test it, but this seems to be the right way I'm looking for. – AppFell Jan 11 '19 at 20:22
  • I edited my question below and tried to implement your solution by using FileChannel instead of byte[]. What is wrong in my code? By indexing the buffers position pointer to zero (ByteBuffer.clear()) and using ByteBuffer.getLong() the first 8 bytes are read. Why this wrong fileSize? The sender clear its writeBuffer and puts the filesize to the beginning of the ByteBuffer. – AppFell Jan 12 '19 at 18:10
  • Try this why? It still makes the same invalid assumption as the original code, that the length read will be the length written. It ain't necessarily so. – user207421 Jan 19 '19 at 05:32