我正在尝试实现这样的事情:通过文件选择器选择了一个文件,我将它翻译成一个字符串,并在聊天中以 10k 字节为单位将其发送到服务器。以下是选择和剪切文件的方式:
requestCode == 1 && resultCode == Activity.RESULT_OK -> {
if (data != null) {
val fileUri = data.data!!
val partSize = 10000
val fileString = readTextFile(fileUri)
var name = ""
var size: Long? = null
fileUri.let { returnUri ->
contentResolver.query(returnUri, null, null, null, null)
}?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
cursor.moveToFirst()
name = cursor.getString(nameIndex)
size = cursor.getLong(sizeIndex)
}
if (fileString!!.length < partSize) {
ws.send(ChatRequestMessages.sendFile(fileString,
name,
selectedContactId.toString(),
fileString.length.toLong(),
0))
} else {
val partsCount = if (size!!.rem(partSize).toInt() == 0) {
size!!.div(partSize)
} else {
size!!.div(partSize)
}
for (currentPart in 0..size!!.div(partSize)) {
val slicedString = if ((currentPart + 1) * partSize <= size!!.toInt()) {
fileString.substring(currentPart.toInt() * partSize..(currentPart + 1).toInt() * partSize)
} else {
fileString!!.substring(currentPart.toInt() * partSize until fileString.length)
}
Timber.i("${fileString.length.toLong()} ${currentPart * partSize} ${slicedString.length} $slicedString $name")
ws.send(ChatRequestMessages.sendFile(slicedString,
name,
selectedContactId.toString(),
fileString.length.toLong(),
(currentPart * partSize).toInt()))
}
}
}
}
然后出现一个奇怪的情况:例如14字节的文件,一切正常发送,3 kb的文件也可以,但是当我尝试发送12.15 kb的文件时,出现以下错误:
[okio.RealBufferedSource.require(RealBufferedSource.kt:201), okio.RealBufferedSource.readByte(RealBufferedSource.kt:210), okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119), okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102), okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293), okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195), okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:504), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636), java.lang.Thread.run(Thread.java:764)]
当我发送一个 120kb 的文件时,我收到以下错误:
Read error: ssl=0xdbda0ac0: I/O error during system call, Connection reset by peer null [com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method), com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:741), okio.InputStreamSource.read(JvmOkio.kt:90), okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:129), okio.RealBufferedSource.request(RealBufferedSource.kt:207), okio.RealBufferedSource.require(RealBufferedSource.kt:201), okio.RealBufferedSource.readByte(RealBufferedSource.kt:210), okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119), okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102), okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293), okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195), okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:504), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636), java.lang.Thread.run(Thread.java:764)]
我不明白出了什么问题,什么影响了文件大小。也许有人有类似的问题,他解决了,我将不胜感激任何信息:)
错误很简单地从服务器端确定。为此,您要么需要访问后端,要么需要与开发人员沟通。结果,通过终端启动服务器,收到了一个更容易理解的错误:
错误的本质是服务器编解码器无法处理传输的字符串。为了发送通常被服务器咀嚼的普通字符串,您需要根据此标准对您拥有的字符串进行编码:
维基百科有这样的澄清:
因此,这就是服务器所需要的。