在 Golang Server 中接受持久的 tcp 连接

2024-04-30

我正在尝试使用 Go - 并且想创建一个 TCP 服务器,我可以通过 telnet 访问该服务器,发送命令并接收响应。

const (
    CONN_HOST = "localhost"
    CONN_PORT = "3333"
    CONN_TYPE = "tcp"
)

func main() {

    listener, err := net.Listen(CONN_TYPE, fmt.Sprintf("%s:%s", CONN_HOST, CONN_PORT))
    if err != nil {
        log.Panicln(err)
    }

    defer listener.Close()

    for {
        conn, err := listener.Accept()
        if err != nil {
            log.Panicln(err)
        }

        go handleRequest(conn)
    }
}

func handleRequest(conn net.Conn) {
    buffer := make([]byte, 1024)

    length, err := conn.Read(buffer)
    if err != nil {
        log.Panicln(err)
    }

    str := string(buffer[:length])

    fmt.Println(conn.RemoteAddr().String())
    fmt.Printf("Received command %d\t:%s\n", length, str)

    switch str {
        case "PING\r\n":
        sendResponse("PONG", conn)
        case "PUSH\r\n":
        sendResponse("GOT PUSH", conn)
    default:
        conn.Write([]byte(fmt.Sprintf("UNKNOWN_COMMAND: %s\n", str)))
    }

    conn.Close() // closes the connection
}

func sendResponse(res string, conn net.Conn) {
    conn.Write([]byte(res+"\n"))
}

上面的代码片段每次都会关闭连接,将我踢出终端会话。但我真正想要的是能够保持连接打开以进行更多 I/O 操作。如果我简单地删除conn.Close(),那么服务器似乎挂在某处,因为它没有收到任何更多响应。

我解决这个问题的方法是让我的handleRequest方法无限循环,这样它就不会退出,直到它收到一个QUIT\r\n信息。这是否合适——或者有更好的实现方法吗?

func handleRequest(conn net.Conn) {
    for {
        log.Println("Handling Request")
        buffer := make([]byte, 1024)

        length, err := conn.Read(buffer)
        if err != nil {
            log.Panicln(err)
        }

        str := string(buffer[:length])

        fmt.Println(conn.RemoteAddr().String())
        fmt.Printf("Received command %d\t:%s\n", length, str)

        switch str {
        case "PING\r\n":
            sendResponse("PONG", conn)
        case "PUSH\r\n":
            sendResponse("GOT PUSH", conn)
        case "QUIT\r\n":
            sendResponse("Goodbye", conn)
            conn.Close()
        default:
            conn.Write([]byte(fmt.Sprintf("UNKNOWN_COMMAND: %s\n", str)))
        }
    }
}

您的第二个循环示例已经是您想要的。您只需循环并读取任意时间(或者可能直到某个读/写超时或外部取消信号)。

然而它仍然有一个错误: TCP 为您提供字节流,但不能保证一侧的一次写入会在另一侧产生具有相同数据长度的一次读取。这意味着如果客户端写PING\r\n您仍然只能收到PI在第一次阅读中。你可以通过使用来解决这个问题bufio.Scanner并始终读到第一个换行符。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Golang Server 中接受持久的 tcp 连接 的相关文章

  • 为什么结构中“[0]byte”的位置很重要?

    0 byte在golang中不应该占用任何内存空间 但这两个结构体的大小不同 type bar2 struct A int 0 byte type bar3 struct 0 byte A int 那么为什么这个位置 0 byte这里重要吗
  • 如何分析 VSCode 中函数的性能

    我用 C Golang 编写了一个程序 如何找到占用最高 CPU 周期的函数 目的是提高正在执行的程序的性能 2021 年 10 月 金香儿哈娜 https github com hyangah宣布 tweet https twitter
  • 如何解析 Content-Disposition 标头以检索文件名属性?

    使用 go 如何解析从 http HEAD 请求检索到的 Content Disposition 标头以获取文件的文件名 此外 如何从 http HEAD 响应中检索标头本身 这样的事情正确吗 resp err http Head http
  • 如何在 Go 应用程序中处理打开/关闭数据库连接?

    我的 Web API 应用程序中有一组函数 他们对 Postgres 数据库中的数据执行一些操作 func CreateUser db err sql Open postgres user postgres password passwor
  • for 循环初始值设定项中的结构

    知道为什么 for 循环初始值设定项中的这个结构表达式在编译时会出现语法错误吗 在这种情况下 指向结构的指针工作正常 但 ofc 我需要如下所示的局部变量 感谢您的建议 type Request struct id int line byt
  • GOPATH值设置

    我用go1 3 1 windows amd64 msi安装go 安装后GOROOT是默认设置 我发现 D Programs Go bin 在 PATH 中 然后我创建一个 GOPATH 环境变量 使用 go get 命令时 出现错误 软件包
  • 我怎么知道我的所有 goroutine 确实正在使用 golang 的同步包等待一个条件

    我有一个应用程序 我正在创建多个 goroutine 来同时执行某个任务 所有工作协程都会等待条件 事件发生 一旦事件被触发 它们就会开始执行 创建完所有goroutines后 主线程在发送广播信号之前应该知道所有goroutines确实处
  • 模板中的 bson.ObjectId

    我有一个具有 bson ObjectId 类型的结构 例如如下所示 type Test struct Id bson ObjectId Name string Foo string 我想在 html 模板中呈现它 Name Food a h
  • 解组转义 XML

    在 Go 中 我将如何解码此 XML 响应 我尝试过建立一个自定义UnMarshal方法在我的Answerstruct 但我运气不太好
  • C++套接字256字节缓冲区

    我正在尝试在 C 中使用一些套接字网络编程 我正在尝试发送文本 Hello World 使用 C send 函数发送到服务器 首先 我将缓冲区的大小设置为 13 因为 Hello World 总共是 12 个字符 必须比字符数多 1 个 如
  • 在 Go 中初始化嵌入结构

    我有以下内容struct其中包含一个net http Request type MyRequest struct http Request PathParams map string string 现在我想初始化匿名内部结构http Req
  • 使用 boost 异步发送和接收自定义数据包?

    我正在尝试使用 boost 异步发送和接收自定义数据包 根据我当前的实现 我有一些问题 tcpclient cpp include tcpclient h include
  • 通过 Telnet 运行应用程序

    我需要创建一个 BAT 文件来通过 telnet 运行应用程序 但据我所知 在 DOS 上无法执行此操作 Telnet 不允许在连接的瞬间向远程计算机发送任何命令 并且 BAT 文件中的每个后续命令只有在 telnet 停止后才会执行 这段
  • 有队列实现吗?

    任何人都可以建议使用 Go 容器来实现简单快速的 FIF 队列 Go 有 3 种不同的容器 heap list and vector 哪一种更适合实现队列 事实上 如果您想要的是一个基本且易于使用的 fifo 队列 slice 可以满足您所
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • ADO.NET SQLServer:如何防止关闭的连接持有S-DB锁?

    i Dispose http msdn microsoft com en us library system data sqlclient sqlconnection close aspx一个 SqlConnection 对象 但是当然它并
  • 如何抑制Windows防火墙的Windows安全警报?

    当我从这里找到的 ZeroMQ 指南中用 C 创建 Hello World 示例时 http zguide zeromq org page all Ask and Ye Shall Receive http zguide zeromq or
  • 为什么 char name[1] 可以容纳超过 1 个字符? [复制]

    这个问题在这里已经有答案了 当我遇到这种情况时 我正在对一个主题进行一些研究 假设有以下 C 代码 include
  • 与通道相比,sync.WaitGroup 的优势是什么?

    我正在开发一个并发 Go 库 我偶然发现了 goroutine 之间两种不同的同步模式 其结果相似 等待组 https play golang org p ZYPLlcp16TZ package main import fmt sync t
  • 为什么 gmail API 以纯文本形式发送 html 电子邮件?

    我正在尝试使用 gmail API 发送 html 电子邮件 但由于某些原因 它会随机以纯文本 文本形式发送电子邮件 谷歌似乎改变了我设置的内容类型标头 这有什么理由吗 电子邮件内容始终完全相同 正如我测试的那样 API 仍处于实验阶段吗

随机推荐

  • 使用线程和 ruby​​ mechanize 安全吗?

    有没有人见过很多这样的错误 Exception Net HTTPBadResponse at usr lib ruby 1 8 net http rb 2022 wrong status line SOME HTML CODE HERE 何
  • 为什么需要在父子组件中多次导入React?

    如果您有已导入的父组件文件React 为什么它的任何渲染的子文件也需要导入 React 这是否只是一种安全措施 以防这些子项被渲染到尚未导入 React 的其他地方 In nodejs每个文件都是一个模块 有自己的变量范围 当您将变量导入文
  • 如何通过服务帐户使用 Terraform `google_app_engine_domain_mapping`?

    我正在尝试使用以下配置通过 Terraform 创建 GCP App Engine 域映射 provider google version 3 36 0 region var region resource google app engin
  • 当我停止我的应用程序后,IntentService 将被终止

    我指的是android 设计注意事项 AsyncTask 与 Service IntentService https stackoverflow com questions 3817272 android design considerat
  • 如何防止双击时选择 HTML5 画布外部的文本?

    在我尝试过的每个浏览器中 双击 HTML5 画布会选择紧跟在画布元素后面的任何文本 我更愿意将点击次数限制在画布上 注意 我不想完全禁用文本选择 例如 像this https stackoverflow com questions 8805
  • Python套接字模块:Recv()数据响应被切断

    解释 我目前正在尝试使用 python 脚本控制智能电源板 为了实现这一点 我使用了带有套接字模块的 TCP 连接 大约 75 的情况下 我会得到我正在寻找的响应 数据 并且一切都运行良好 然而 大约 25 的情况下 响应会以完全相同的长度
  • 在 DB2 中使用什么来表示 CURRENT_TIMESTAMP?

    我正在将一些 MySQL 语句转换为 DB2 数据库 但我在以下查询中遇到了问题 CREATE TABLE RFX EVENT MAPPING EVENT TYPE varchar 4 NOT NULL EVENT DESC varchar
  • 在 JavaScript 中的空数组上使用 foreach 循环[重复]

    这个问题在这里已经有答案了 我发现我不能在 javascript 中的空数组上使用 for every 循环 谁能向我解释这是为什么 我已经在 javascript 中初始化了一个数组 如下所示 var arr new Array 10 当
  • shouldChangeCharactersInRange 在 Swift 中如何工作?

    我在用着应该改变范围内的字符作为使用即时类型搜索的一种方式 然而我有一个问题 应该改变范围内的字符在文本字段实际更新之前被调用 在 Objective C 中 我使用以下方法解决了这个问题 BOOL textField UITextFiel
  • 在 SQL 存储过程中选择并合并表中的行

    有一个具有架构的临时表 ID 序列号 姓名 ID 不唯一SeqNo 整数 可以是 1 2 或 3 以ID SeqNo作为主键排序名称 任何文本 表中的示例数据如下 1 1 RecordA 2 1 RecordB 3 1 RecordC 1
  • 如何将 Jar 库添加到 IntelliJ Idea SBT Scala 项目?

    我创建了一个 IntelliJ Idea SBT Scala 项目 例如海科 西伯格的文章 http heikoseeberger blogspot com 2010 08 how to setup scala project with s
  • 用 CSS 设置背景图像的大小?

    可以用CSS设置背景图片的大小吗 我想做类似的事情 background url bg gif top repeat y background size 490px 但这样做似乎是完全错误的 CSS2 如果需要放大图像 则必须在图像编辑器中
  • jquery中元素+ ID vs 只有ID?

    div some id将扫描整个 DOM 中的所有 div some id将直接从 DOM 获取 ID 那么哪个更快呢 div some id or some id See 优化选择器 https learn jquery com perf
  • Azure 搜索 .NET SDK 自定义分析器

    没有太多背景 这是我的问题 要使用 C 中的 NET SDK 创建新的 Azure 搜索索引 使用文档中提供的酒店示例 我的代码如下所示 public class Hotel System ComponentModel DataAnnota
  • adb 可以检测的设备数量是否有上限

    我想知道 android adb 工具可以检测的设备数量是否有最大限制 我在谷歌上没有找到任何答案 我已经成功连接了 13 台设备 但我不知道它是否仍然适用于更多设备 Thanks 似乎没有 adb 限制 但有一个 USB 控制器限制 具体
  • IOS内存中存储userid

    我做了一个带有登录功能的IOS应用程序 我使用 ASIHTTPRequest 来检查用户是否存在于 MySQL 数据库中 一切正常 但我想通过其他视图控制器传递用户 ID 或在应用程序的其他部分检索它 有人可以推动我朝着正确的方向前进 如何
  • ConfigParser 从 INI 文件中获取值,如下所示

    我有以下类型的 INI 文件 section1 subsection1 port 989 section1 subsection2 somethign somethign 我正在使用 Python 的 ConfigParser 来解析 IN
  • 在不同节点上运行 Jenkins stage

    我有以下多分支管道架构的 Jenkinsfile usr bin groovy pipeline agent node label ubuntu customWorkspace src BUILD NUMBER environment SR
  • VBA Excel:将条件格式应用于空白单元格

    我正在尝试编写一个子过程 它将一些条件格式应用于 Excel 中的一系列单元格 我有点卡住了 所以我使用了宏录制器 然而 我无法弄清楚为什么它应用下面的公式 并且当我手动运行代码时它失败了 我想要做的是将条件格式应用于范围内的空白单元格 我
  • 在 Golang Server 中接受持久的 tcp 连接

    我正在尝试使用 Go 并且想创建一个 TCP 服务器 我可以通过 telnet 访问该服务器 发送命令并接收响应 const CONN HOST localhost CONN PORT 3333 CONN TYPE tcp func mai