当前位置: 首页 > 面试题库 >

Golang:TCP客户端/服务器数据定界符

乐正远
2023-03-14
问题内容

不确定如何提出问题以及它是否仅与go语言有关,但我想做的是让tcp服务器和客户端之间进行数据交换,基本上,客户端会将大量数据流化为较小的数据如果将数据块发送给服务器,则服务器将等待读取每个数据块,然后回复状态码,客户端将读取该状态码,并基于此状态码执行其他工作。

我使用下面的功能作为 测试 从客户端和服务器读取数据的方法(请注意,我知道这并不完美,但这只是测试):

func createBufferFromConn(conn net.Conn) *bytes.Buffer {
    buffer := &bytes.Buffer{}
    doBreak := false
    for {
        incoming := make([]byte, BUFFER_SIZE)

        conn.SetReadDeadline(time.Now().Add(time.Second * 2))
        bytesRead, err := conn.Read(incoming)
        conn.SetReadDeadline(time.Time{})

        if err != nil {
            if err == io.EOF {
                fmt.Println(err)
            } else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
                fmt.Println(err)
            }
            doBreak = true
        }

        if doBreak == false && bytesRead == 0 {
            continue
        }

        if bytesRead > 0 {
            buffer.Write(incoming[:bytesRead])
            if bytes.HasSuffix(buffer.Bytes(), []byte("|")) {
                bb := bytes.Trim(buffer.Bytes(), "|")
                buffer.Reset()
                buffer.Write(bb)
                doBreak = true
            }
        }

        if doBreak {
            break
        }
    }
    return buffer
}

现在在我的情况下,如果我通过telnet连接(go代码还包括一个client()连接到的连接server()),并且我输入了一些类似test 12345|公平的东西,则一切正常,并且缓冲区包含了所有从telnet写入的字节(除非被删除的管道Trim()调用)。

如果我if bytes.HasSuffix(buffer.Bytes(), []byte("|")) {从代码中删除该块,那么我将在2秒后再次超时,这是按预期的,因为在该时间内没有接收到任何数据,并且服务器关闭了连接,并且如果我没有设置从连接后,它将永远等待读取数据,并且永远不知道何时停止。

我想我的问题是,如果我发送多个数据块,是否必须指定自己的分隔符,以便我知道何时停止从连接中读取并避免永远等待或等待服务器使连接超时?


问题答案:

我想我的问题是,如果我发送多个数据块,是否必须指定自己的分隔符,以便我知道何时停止从连接中读取数据,并避免永远等待或等待服务器使连接超时

是。TCP是一种流协议,如果不对消息进行某种形式的框架化,就无法确定协议中消息的开始和停止位置。

使用的更常见的成帧方法是发送大小前缀,以便接收器 无需 缓冲结果并扫描定界符 即可
知道要读取多少内容。这可以很简单message_length:data....(另请参见netstring和type-
length-value
编码)。



 类似资料:
  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • 问题内容: 我正在寻找一些通用策略,用于将中央服务器上的数据与并不总是在线的客户端应用程序进行同步。 在我的特定情况下,我有一个带sqlite数据库的android手机应用程序和一个带MySQL数据库的PHP Web应用程序。 用户将能够在电话应用程序和Web应用程序上添加和编辑信息。我需要确保即使手机无法立即与服务器通信,在一个地方所做的更改也会在所有地方反映出来。 我不关心如何将数据从手机传输

  • 前面的章节介绍了所有 Redis 的重要功能组件: 数据结构、数据类型、事务、Lua 环境、事件处理、数据库、持久化, 等等, 但是我们还没有对 Redis 服务器本身做任何介绍。 不过, 服务器本身并没有多少需要介绍的新东西, 因为服务器除了维持服务器状态之外, 最重要的就是将前面介绍过的各个功能模块组合起来, 而这些功能模块在前面的章节里已经介绍过了, 所以本章将焦点放在服务器的初始化过程,

  • 问题内容: 我正在尝试在Java中的服务器和JavaScript客户端之间建立连接,但在客户端出现此错误: WebSocket与“ ws://127.0.0.1:4444 /”的连接失败:在收到握手响应之前,连接已关闭 由于可能从未调用该函数,因此它可能保持在OPENNING状态。该不会被调用。 有人可以让我知道这里出了什么问题吗? 服务器 服务器线程 游戏协议 客户 问题答案: 首先,您的两个代

  • 问题内容: 我尝试使用以下代码从服务器到客户端发送文件和目录列表。服务器正在从客户端接收消息,但我不知道服务器是否没有发送回结果或客户端是否不接受结果。 服务器端: 问题答案: 据我所见,您在客户端上做的同时在服务器上做。从服务器发送的字符串中没有行尾字符,因此客户端将永远无法完成。执行outqw.println()或添加到要发送的内容的末尾。话虽这么说,很难用一堆注释掉的东西来浏览未格式化的代码