简体   繁体   中英

Android Socket TCP Dataloss

I am unable to transmit an entire file using WiFi-Direct. The file sender is indicating that the entire file has been copied over to the socket output stream. The file receiver is only receiving roughly half of the file.

I looked at the contents of both the original file and the contents of the file storing the received data, and found the receiver is only receiving pieces of the original file. For example, it would receive bytes 0-100, and then it would jump to byte 245-350.

Why is the receiver only receiving bits and pieces of the file, rather than the entire file?

File Receiving Logic

    private class FileReceiveThread(val channel: Channel) : TransmissionThread() {
        private var mFileName: String = ""
        private var mFileSize: Long = 0L
        private var mBytesReceivedTotal = 0L

        override fun run() {
            try {
                Timber.d("File receive thread running: fileSize=$mFileSize, fileName=$mFileName")
                val outputFile = File.createTempFile("file", "")
                val fileOutput = outputFile.outputStream()
                val channelInput = channel.getInputStream().unwrap()

                val inputBuffer = ByteArray(FILE_TX_BUFFER_SIZE)
                var bytesReceived = channelInput.read(inputBuffer)

                while (bytesReceived > 0) {
                    fileOutput.write(inputBuffer)
                    mBytesReceivedTotal += bytesReceived
                    Timber.d("Received $mBytesReceivedTotal total bytes")
                    bytesReceived = channelInput.read(inputBuffer)
                }

                onTransmitComplete?.invoke()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        fun start(filename: String, size: Long) {
            mFileName = filename
            mFileSize = size
            start()
        }
    }

File Sending Logic

    private class FileSendThread : TransmissionThread() {
        var mFile: File? = null
        var mOutputStream: OutputStream? = null

        override fun run() {
            if (mFile != null && mOutputStream != null) {
                val inputStream = mFile!!.inputStream()
                val channelStream = mOutputStream!!
                val buffer = ByteArray(FILE_TX_BUFFER_SIZE)

                var bytesRead = inputStream.read(buffer)
                var totalBytesRead = 0L + bytesRead

                while (bytesRead > 0) {
                    Timber.v("Read $bytesRead, total $totalBytesRead")
                    channelStream.write(buffer)
                    bytesRead = inputStream.read(buffer)
                    totalBytesRead += bytesRead
                }

                Timber.d("Wrote file to output stream")

                inputStream.close()

                Timber.d("No more data to send")
                onTransmitComplete?.invoke()
            } else Timber.d("Parameters null: file=$mFile")
        }

        fun start(file: File, stream: OutputStream) {
            mFile = file
            mOutputStream = stream
            start()
        }
    }
           while (inputStream.read(buffer) > 0) {
                channelStream.write(buffer)
            }

The read() will often not fill the complete buffer. Hence if you write the buffer then only as far as it is filled.

           var totalbytesread = 0;
           var nread;
           while ((nread = inputStream.read(buffer)) > 0) {
                channelStream.write(buffer, 0, nread)
                totalbytesread += nread;
            }

           channelStream.close()';

Log the totalbytesread. Your original code would have caused a bigger received file so there is something else to be discovered..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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