Hallo an alle!
Ich habe ein Problem mit dem Senden von Bildern mithilfe von SocketChannels und ByteBuffern.
Da viele Bilder verschickt werden sollen, muss ich auf ein simples Protokoll zurückgreifen, das wie folgt funktionieren soll:
In ein zuvor gecleartes writeBuffer (ByteBuffer) füge ich die Größe der zu übertragenden Bilddatei ein: ByteBuffer.putLong();
Dann folgen die Daten des Bildes, die ebenfalls in das Buffer eingefügt werden. Dann wird geflippt und das writeBuffer über den SocketChannel gesendet.
Auf der Empfängerseite wird immer erst das readBuffer (ByteBuffer) gecleared. Dann wird zunächst die Länge der Bilddatei ausgelesen (ByteBuffer.getLong(). Dann wird das Limit des readBuffers auf DATEILAENGE+8 gesetzt schließlich das readBuffer in einen FileChannel gelesen. Nach diesem Vorgang wird das readBuffer wieder gecleared und auf ein weiteres Bild gewartet.
Nun das Problem: Bei der ersten Übertragung läuft alles einwandfrei. Doch beim zweiten Eintreffen von Daten im readBuffer ergibt ByteBuffer.getLong() plötzlich völlig absurde Werte, z.B. Server erwartet ein Bild der Groesse: 3927928765588602075.
Als Quelltext sieht das ganze wie folgt aus:
Senderseite:
Empfängerseite:
Hinweis: das sind jeweils die relevanten Codeausschnitte!
Ich bin für jede Hilfe dankbar!
Was mache ich falsch?
Ich habe ein Problem mit dem Senden von Bildern mithilfe von SocketChannels und ByteBuffern.
Da viele Bilder verschickt werden sollen, muss ich auf ein simples Protokoll zurückgreifen, das wie folgt funktionieren soll:
In ein zuvor gecleartes writeBuffer (ByteBuffer) füge ich die Größe der zu übertragenden Bilddatei ein: ByteBuffer.putLong();
Dann folgen die Daten des Bildes, die ebenfalls in das Buffer eingefügt werden. Dann wird geflippt und das writeBuffer über den SocketChannel gesendet.
Auf der Empfängerseite wird immer erst das readBuffer (ByteBuffer) gecleared. Dann wird zunächst die Länge der Bilddatei ausgelesen (ByteBuffer.getLong(). Dann wird das Limit des readBuffers auf DATEILAENGE+8 gesetzt schließlich das readBuffer in einen FileChannel gelesen. Nach diesem Vorgang wird das readBuffer wieder gecleared und auf ein weiteres Bild gewartet.
Nun das Problem: Bei der ersten Übertragung läuft alles einwandfrei. Doch beim zweiten Eintreffen von Daten im readBuffer ergibt ByteBuffer.getLong() plötzlich völlig absurde Werte, z.B. Server erwartet ein Bild der Groesse: 3927928765588602075.
Als Quelltext sieht das ganze wie folgt aus:
Senderseite:
Java:
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();
}
Empfängerseite:
Java:
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;
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;
Hinweis: das sind jeweils die relevanten Codeausschnitte!
Ich bin für jede Hilfe dankbar!
Was mache ich falsch?