猿问

使用 net.Conn 连接正确处理读写

我正在尝试使用网络连接进行读写。似乎正在发生的事情是,如果数据进入服务器的速度过快,一些数据将被丢弃或丢失。客户端连接,协商连接,然后我让它快速连续发送 3 个命令来更新状态页面。每个通信都是一个 JSON 字符串,它被转换为一个结构并使用存储的密钥进行解码。

如果我多次单击客户端上的请求(每次生成 3 个以 \n 结尾的 JSON 有效负载),服务器有时会抛出 ERROR: invalid character X after the top-level value。我转储了客户端发送的信息,看起来客户端上有 3 个格式正确的 JSON 条目;在服务器端,似乎其中一个 JSON 有效负载完全丢失,其中一个丢失了前 515 个字符。由于缺少前 515 个字符,因此 JSON 格式不正确,因此封送处理失败。

我的问题是,我能做些什么来防止从连接中读取的数据丢失?我是否遇到某种竞争条件或错误处理如何在连接上读取和发送?

下面基本上是我用于客户端连接处理程序的内容。客户端和服务器协商加密连接,因此有多个对模式和 RSA 状态的引用,并且在正确设置密钥时使用模式 4,以便服务器和客户端可以交换命令和结果。在高层次上,处理程序衍生出一个从连接中读取并将其发送到通道的 goroutine。该字符串被读取并转换为结构。会话的第一部分专门用于“握手”以协商加密密钥并保存会话信息;一旦到达第 4 阶段,该结构就会携带来自客户端的加密命令并将结果发送回,直到连接出错或关闭。


斯蒂芬大帝
浏览 132回答 1
1回答

白板的微信

应用程序将数据发送到缓冲的读取器,然后丢弃读取器和它可能缓冲超过第一行的任何数据。在连接的生命周期内保留缓冲的阅读器:&nbsp; &nbsp; rdr := bufio.NewReader(conClient)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; netData, err := rdr.ReadString('\n')&nbsp; &nbsp; &nbsp; &nbsp; ...您可以通过消除 goroutine 来简化代码(并修复与缓冲区问题无关的其他问题)。使用读取期限来处理无响应的服务器。func HandleClientConnection(conClient net.Conn) {&nbsp; &nbsp; defer conClient.Close()&nbsp; &nbsp; chnLogging <- "Connection from " + conClient.RemoteAddr().String()&nbsp; &nbsp; conClient.SetReadDeadline(time.Minute * SERVER_INACTIVITY_TIMEOUT_MINUTES)&nbsp; &nbsp; scanner := bufio.NewScanner(conClient)&nbsp; &nbsp; for scanner.Scan() {&nbsp; &nbsp; &nbsp; &nbsp; var strctNetEncrypted stctNetEncrypted&nbsp; &nbsp; &nbsp; &nbsp; err := json.Unmarshal(scanner.Bytes(), &strctNetEncrypted)&nbsp; &nbsp; &nbsp; &nbsp; CheckErr(err)&nbsp; &nbsp; &nbsp; &nbsp; switch strctNetEncrypted.IntMode {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Insert contents of switch statement from&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// question here with references to&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// chnCloseConn removed.&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; conClient.SetReadDeadline(time.Minute * SERVER_INACTIVITY_TIMEOUT_MINUTES)&nbsp; &nbsp; }&nbsp; &nbsp; if scanner.Err() != nil {&nbsp; &nbsp; &nbsp; &nbsp; chnLogging <- "Error from client " + conClient.RemoteAddr().String() + ": " + err.Error()&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; chnLogging <- "Client " + conClient.RemoteAddr().String() + " disconnected"&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答