为了账号安全,请及时绑定邮箱和手机立即绑定

bufio 扫描仪和处理新行

bufio 扫描仪和处理新行

Go
aluckdog 2023-07-31 17:04:26
我有 2 个进程通过 TCP 套接字进行通信。A 方向 B 方发送字符串,有时使用标准加密/密码包对其进行加密。生成的字符串可能包含换行符,但 B 方的 bufio 扫描器将其解释为请求的结束。我希望 B 方继续接受行、追加它们并等待已知的命令结束字符,然后再进一步处理它。B 方将向 A 方返回响应,因此连接保持打开状态,因此不能使用关闭连接事件作为命令分隔符。对于单行命令,一切工作正常,但加密输出中的这些新行字符会导致问题(大约 10% 的情况)。A 方将以以下格式发送(第三个是我试图正确处理的问题字符串的合法示例):调用命令()callCommand("一","二","三")callCommand("string","要关注的加密数据","[7b��Cr��l��G����bH�@x��������� �(z�$� a��0��带5Y7+��U�QT�ΐl�K�(�n�U��J����QK�BX�+�l\8H��-g�y.�.�1� f��I�C�ş㳿���o�xz�8?��c�e �Tb�?4�hD W��� �<���Е�gc������ �N�V��P8 ���O3")我们可以相当可靠地说命令结束键是右括号“)”和换行符。A方发送给B方的功能:func writer(text string) string {    conn, err := net.Dial("tcp", TCPdest)    t := time.Now()    if err != nil {        if _, t := err.(*net.OpError); t {            fmt.Println("Some problem connecting.\r\n")        } else {            fmt.Println("Unknown error: " + err.Error()+"\r\n")        }    } else {        conn.SetWriteDeadline(time.Now().Add(1 * time.Second))        _, err = conn.Write([]byte(text+"\r\n"))        if err != nil {            fmt.Println("Error writing to stream.\r\n")        } else {            timeNow := time.Now()                       if timeNow.Sub(t.Add(time.Duration(5*time.Second))).Seconds() > 5 {                return "timeout"            }            scanner := bufio.NewScanner(conn)            for {                ok := scanner.Scan()                if !ok {                    break                }                if strings.HasPrefix(scanner.Text(), "callCommand(") && strings.HasSuffix(scanner.Text(), ")") {                    conn.Close()                    return scanner.Text()                }            }        }    }    return "unspecified error"}B方对传入连接的处理:src := "192.168.68.100:9000"listener, _ := net.Listen("tcp", src)defer listener.Close()for {    conn, err := listener.Accept()    if err != nil {        fmt.Println("Some connection error: %s\r\n", err)    }    go handleConnection(conn)}   我不太确定 B 面的这种方法是否正确,但在上面包含了我的代码。我见过一些实现,但很多似乎依赖于关闭连接来开始处理请求,这不适合我的场景。
查看完整描述

1 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

您的通信“协议”(一行是一条消息,不完全是协议)显然无法处理二进制数据。如果您想在协议中发送文本数据,您可以将二进制数据转换为文本,例如使用 Base64 编码。您还需要一些语义来指示某些文本是从二进制转换而来的。


或者您可以更改协议以本地处理二进制数据。您可以在后面添加二进制数据的长度,这样您就知道必须以二进制形式读取该数据,而不是将换行符解释为消息的结尾。


有许多协议在这方面做得很好,也许您不需要想出您的自定义协议。如果你想发送短信,HTTP 使用起来非常简单,你可以将数据格式化为 JSON,使用 Base64 将二进制数据转换为文本:


{

    "command": "string",

    "args": [

        "binaryDataAsBase64"

    ]

}


查看完整回答
反对 回复 2023-07-31
  • 1 回答
  • 0 关注
  • 104 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信