Error de byte de file en kotlin. Cómo transferir correctamente?

Quiero Transferir file con el cliente tcp al server, pero el file de image ha sido incorrecto.

Mi código de cliente es

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream import org.msgpack.core.MessageBufferPacker import org.msgpack.core.MessagePack import org.msgpack.core.MessageUnpacker import java.io.* import java.net.Socket import java.util.* fun main(args: Array<String>) { fileClient("localhost",1988,"fruit.jpg") } class fileClient (host:String, port:Int, file:String){ var s : Socket ?= null var out = ByteArrayOutputStream() var msg : MessageBufferPacker = MessagePack.newDefaultBufferPacker() init { try { s = Socket(host,port) sendFile(file) }catch (e:Exception){ e.printStackTrace() } } @Throws(IOException::class) fun sendFile(file: String) { val dos = DataOutputStream(s!!.getOutputStream()) val buffer = ByteArray(4096) val filebytes = File(file).readBytes() var msgdata = ByteOutputStream() msg.packString(file) msg.packBinaryHeader(filebytes.size) msg.writePayload(filebytes) msg.close() val data = msg.toByteArray() val datasize = data.size val ins = ByteArrayInputStream(data) dos.writeInt(datasize) while (ins.read(buffer) > 0) { dos.write(buffer) } dos.close() } } 

Y mi código de server es

 import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream import org.msgpack.core.MessagePack import org.msgpack.core.MessageUnpacker import java.awt.List import java.io.* import java.net.ServerSocket import java.net.Socket import java.text.SimpleDateFormat import java.util.* fun main(args: Array<String>) { var fs = FileServer(1988) fs.start() } class FileServer(port: Int) : Thread() { private var ss: ServerSocket? = null var fileRealName : String ?= null init { try { ss = ServerSocket(port) } catch (e: IOException) { e.printStackTrace() } } override fun run() { while (true) { try { val clientSock = ss!!.accept() saveFile(clientSock) } catch (e: IOException) { e.printStackTrace() } } } @Throws(IOException::class) private fun saveFile(clientSock: Socket) { var msgList = ArrayList<Any>() val dis = DataInputStream(clientSock.inputStream) val msgdata = ByteOutputStream() val buffer = ByteArray(4096) var read = 0 while (true) { val datalen = dis.readInt() // data length if(datalen!= null && datalen >0){ var finaldata = ByteArray(datalen) var process = 0; while (process <= datalen) { read = dis.read(buffer) if (read < 0) { return } msgdata.write(buffer) process += 4096 } println(process.toString() + " "+ datalen.toString()) var allData = msgdata.toByteArray().slice(0..datalen).toByteArray() unpackByte(allData) } } msgdata.close() dis.close() } private fun unpackByte(data:ByteArray){ var unpacker : MessageUnpacker = MessagePack.newDefaultUnpacker(data) var fileName = unpacker.unpackString().toString() var filesize = unpacker.unpackBinaryHeader() var buffer = ByteArray(filesize) unpacker.readPayload(buffer) var fos = FileOutputStream(fileName) fos.write(buffer) fos.close() unpacker.close() } } 

Y un file que quiero transferir es enter image description here

pero después de la transferencia, la image en el server es así. enter image description here

¿Cómo puedo transferir este file correctamente?

No tuve éxito en reproducir tu problema. Sin embargo, creo que he encontrado el error que puede estar causando la transferencia de files corruptos.

En su código de server hay un bucle infinito que regresa inmediatamente fuera del método dejando el rest del método inalcanzable. Este es el código de limpieza que cierra las conexiones y las transmisiones. Muy posiblemente, OutputStream no se cerró correctamente y esta es la causa de la escritura de files corruptos.

Así es como debería verse el código del server:

 val datalen = dis.readInt() // data length if (datalen > 0) { var finaldata = ByteArray(datalen) var process = 0; while (process <= datalen) { read = dis.read(buffer) if (read < 0) { break } msgdata.write(buffer) process += 4096 } println(process.toString() + " " + datalen.toString()) val allData = msgdata.toByteArray().slice(0..datalen).toByteArray() unpackByte(allData) } msgdata.close() dis.close() 

while loop es innecesario. También es probable que solo deba break el ciclo, no return de la function.

PD: ¿Ha considerado usar IOUtils para manejar todas las lecturas / escrituras IO? La mitad de su código podría replacese con solo unas pocas líneas de código usando esta biblioteca.