go - 有没有办法优化该代码?Go中的TCP服务器
问题描述
编码器。这是基本的 tcp-server,它接受连接,读取传入的数据并写回。
package main
import (
"bufio"
"io"
"log"
"net"
)
func main() {
li, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatalln(err)
}
defer li.Close()
for {
conn, err := li.Accept()
if err != nil {
log.Fatalln(err)
}
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
ln := scanner.Text()
io.WriteString(conn, ln+"\n")
}
conn.Close()
}
}
但是,扫描仪有一个嵌套循环,并在每次外部循环迭代时声明新的扫描仪。我听说嵌套循环会导致额外的复杂性,并且可能在无限循环的每次迭代中声明新的扫描程序会导致一些内存泄漏。实际上,我不知道如何以另一种方式做到这一点,我只想问两件事:
是否有可能以另一种方式做同样的事情?
我们真的需要对这种低级服务器
抽象进行更多优化吗?
解决方案
外循环正在等待新的连接,内循环正在解析输入数据,所以从这个角度来看它很好。并非所有嵌套循环都是邪恶的。但是,当您处理该单个连接时,服务器不再接受它们(您可以通过尝试从多个客户端连接到服务器来测试)。要解决这个问题,请在 goroutine 中处理连接:
for {
conn, err := li.Accept()
if err != nil {
log.Fatalln(err)
}
go func() {
defer conn.Close()
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
ln := scanner.Text()
io.WriteString(conn, ln+"\n")
}
}()
}
推荐阅读
- typescript - 使用 TypeScript 定义类型的键作为属性类型
- python - KeyError:尝试模拟 DynamoDB 时的“操作”
- javascript - 页面加载时文本无效
- java - 莱布尼茨级数循环不收敛
- spring - 在由 MongoDB 支持的 Spring Data REST 存储库中使用自定义 ID
- mysql-8.0 - 为什么我不能再使用 MySQL 8.0 从表“组”中选择数据
- mysql - 跨mysql和redshift不同数据库和不同服务器的查询
- c++ - 在不弹出对话框的情况下中止基于 MFC 的 C++
- list - 使用 foldr 和 lambda 表达式作为其第一个参数
- elasticsearch - 如何对“桶”内的“按字母顺序”对聚合函数进行排序