You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin Socket通信中发送含\a\b的转义序列?

在Kotlin中向Socket发送以"\a\b"结尾的消息问题

我们在大学项目中需要编写与客户端通信的服务器,服务器和机器人通过纯文本协议交互,每条命令必须以特殊符号组合\a\b结尾。

在Python中可以轻松实现:

sock.sendall("message\a\b".encode())

但在Kotlin中,\a不是有效转义序列,执行client.getOutputStream().write("message\a\b".toByteArray())会报错“\a是非法转义序列”。我尝试用\a的Unicode等效序列\u0007编写代码:

client.getOutputStream().write("Message\u0007\b".toByteArray())

可客户端仍无法识别为\a\b,无法理解消息。下面是我的完整ClientHandler类代码:

import java.io.OutputStream
import java.net.Socket
import java.util.Scanner

class ClientHandler(private val client: Socket) {

    private val reader: Scanner = Scanner(client.getInputStream())
    private val writer: OutputStream = client.getOutputStream()
    private var running: Boolean = false

    lateinit var username: String
    lateinit var hash: String
    lateinit var clientHash: String
    var key: Int = 0
    var direction: Int = 0
    lateinit var currenCoordinates: Coordinates
    lateinit var previousCoordinates: Coordinates
    lateinit var messageStore: String


    fun run() {
        running = true
        try {
            getUsername()
            sendKeyRequest()
        } catch (ex: Exception) {
            shutdown()
        } finally {
        }
    }

    private fun getUsername() {
        val username = reader.nextLine().toString()
        writer.write("Message".toByteArray(Charsets.US_ASCII))
        writer.flush()
        client.close()
        println(username)
    }

    private fun write(message: String) {
        writer.write("Message".toByteArray(Charsets.US_ASCII))
        writer.flush()
        println("Sent Message: $message")
    }

    private fun sendKeyRequest() {
        write("107 KEY REQUEST\u0007\b")
    }

    private fun shutdown() {
        running = false
        client.close()
        println("Connection was closed")
    }

    private fun calculateHash(username: String): Int {
        var sum: Int = 0

        for (char in username) {
            sum = char.code
        }
        return (sum * 1000) % 65536
    }

}

data class Coordinates(val x: Int, val y: Int)

解决方案

核心问题分析

你遇到的问题根本不是\u0007\b的转义问题,而是你的write方法完全没有发送传入的消息内容——它固定写死了字符串"Message",完全忽略了参数message。另外还要确保编码和Python一致(用US-ASCII),避免字节差异。

修正步骤

  1. 定义消息终止符常量:把\a\b对应的Unicode转义封装成常量,方便复用和维护
  2. 修复write方法:正确发送传入的消息内容,并自动追加终止符
  3. 修正其他逻辑错误(比如getUsername里提前关闭客户端导致后续代码无法执行、calculateHash的求和逻辑错误)

修正后的代码片段

class ClientHandler(private val client: Socket) {

    private val reader: Scanner = Scanner(client.getInputStream())
    private val writer: OutputStream = client.getOutputStream()
    private var running: Boolean = false
    private val MESSAGE_TERMINATOR = "\u0007\b" // 对应协议要求的\a\b

    // ... 其他成员变量保持不变 ...

    fun run() {
        running = true
        try {
            getUsername()
            sendKeyRequest()
        } catch (ex: Exception) {
            shutdown()
        }
    }

    private fun getUsername() {
        username = reader.nextLine().toString()
        write("Message") // 使用修正后的write方法发送消息
        println(username)
        // 不要在这里关闭client,否则sendKeyRequest无法执行
    }

    private fun write(message: String) {
        // 拼接消息内容和终止符,用US-ASCII编码生成字节数组
        val fullMessage = message + MESSAGE_TERMINATOR
        writer.write(fullMessage.toByteArray(Charsets.US_ASCII))
        writer.flush()
        println("Sent Message: $fullMessage")
    }

    private fun sendKeyRequest() {
        // 不用手动加终止符,write方法会自动处理
        write("107 KEY REQUEST")
    }

    private fun calculateHash(username: String): Int {
        var sum = 0
        // 修正求和逻辑:累加每个字符的code,而不是覆盖
        for (char in username) {
            sum += char.code
        }
        return (sum * 1000) % 65536
    }

    // ... 其他方法保持不变 ...
}

说明

  • \u0007确实是ASCII响铃字符(对应\a),\b是退格字符,两者组合就是协议要求的终止符
  • 使用Charsets.US_ASCII编码和Python的encode()默认行为一致,避免因编码差异导致字节不匹配
  • 修复后的write方法会自动处理终止符,避免重复编写转义序列,减少出错概率
  • 移除getUsername里的client.close(),否则后续的sendKeyRequest根本无法执行

内容的提问来源于stack exchange,提问作者user9048037

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 02:17:49