java - Android Socket TCP 数据丢失

标签 java android sockets tcp ftp

我无法使用 WiFi-Direct 传输整个文件。文件发送者指示整个文件已被复制到套接字输出流。文件接收器仅接收大约一半的文件。

我查看了原始文件的内容和存储接收到的数据的文件的内容,发现接收方仅接收原始文件的部分内容。例如,它会接收字节0-100,然后跳转到字节245-350。

为什么接收方只接收文件的一些 fragment ,而不是整个文件?

文件接收逻辑

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

文件发送逻辑

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

read() 通常不会填满整个缓冲区。因此,如果您写入缓冲区,则只能写入缓冲区。

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

           channelStream.close()';

记录读取的总字节数。 您的原始代码会导致接收到的文件更大,因此还有其他东西需要发现..

关于java - Android Socket TCP 数据丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58980618/

相关文章:

使用 Feinstein SldingMenu 和 AppCompat v21 的 Android L ActionBarActivity 在屏幕底部被截断

linux - CouchDB 更改数据库目录

c# - Non-Blocking IO是如何实现的?

java - Spring Boot - 不使用 WebSecurityConfigurerAdapter 的自定义身份验证过滤器

java - 基于参数的类的新实例

java - 如何将 Java 字节数组直接发送到 MATLAB 矩阵?

node.js - 通过带有流的代理通过 tcp 套接字发送文件

java - Spring MVC 无法加载 CSS

android - KeyboardDidShow/Hide 事件在具有 adjustResize 设置的 Android 上不起作用

android - 数据绑定(bind) : How to get resource by dynamic id?