go tcp客户端自动重连_在Go中构建并发TCP服务器样例

02ba5961a28fde104cd39fdfaf71e8c3.png

开发一个并发TCP服务器,只使用大约65行Go代码生成随机数。

本文是Mihalis Tsoukalos的Go系列的一部分。阅读第1部分:在Go中创建随机安全密码。

TCP和UDP服务器无处不在,通过TCP / IP网络为网络客户端提供服务。在本文中,我将解释如何使用Go编程语言开发一个返回随机数的并发TCP服务器。对于来自TCP客户端的每个传入连接,TCP服务器将启动一个新的goroutine来处理该请求。

你可以在GitHub上找到这个项目,concTCP.go。

处理TCP连接

该程序的逻辑可以在handleConnection()函数的Go代码中找到,其实现如下:

func handleConnection(c net.Conn) {
        fmt.Printf("Serving %sn", c.RemoteAddr().String())
        for {
                netData, err := bufio.NewReader(c).ReadString('n')
                if err != nil {
                        fmt.Println(err)
                        return
                }

                temp := strings.TrimSpace(string(netData))
                if temp == "STOP" {
                        break
                }

                result := strconv.Itoa(random()) + "n"
                c.Write([]byte(string(result)))
        }
        c.Close()
}

编程和开发

  • 新的Python内容
  • 我们最新的JavaScript文章
  • 最近的Perl帖子
  • 红帽开发者博客

如果TCP客户端发送“STOP”字符串,则服务该特定TCP客户端的goroutine将终止;否则,TCP服务器会将随机数发送回TCP客户端。for只要TCP客户端需要,循环就确保TCP客户端将被服务。for循环中的Go代码逐行读取来自TCP客户端的数据,使用bufio.NewReader(c).ReadString('n')并使用发回数据c.Write([]byte(string(result)))。(您可能会发现净标准Go包文档很有帮助。)

并发

main()函数的实现告诉TCP服务器每次必须为TCP客户端提供服务时都要启动一个新的goroutine:

func main() {
        arguments := os.Args
        if len(arguments) == 1 {
                fmt.Println("Please provide a port number!")
                return
        }

        PORT := ":" + arguments[1]
        l, err := net.Listen("tcp4", PORT)
        if err != nil {
                fmt.Println(err)
                return
        }
        defer l.Close()
        rand.Seed(time.Now().Unix())

        for {
                c, err := l.Accept()
                if err != nil {
                        fmt.Println(err)
                        return
                }
                go handleConnection(c)
        }
}

首先,main()确保程序至少有一个命令行参数。请注意,现有代码不会检查给定的命令行参数是否是有效的TCP端口号。但是,如果给定值不是有效的TCP端口号,则调用net.Listen()将失败,并显示类似于以下内容的错误消息:

$ go run concTCP.go 12a
listen tcp4: lookup tcp4/12a: nodename nor servname provided, or not known
$ go run concTCP.go -10
listen tcp4: address -10: invalid port

net.Listen()调用用于告知Go程序接受网络连接,从而充当服务器。返回值net.Listen()net.Conn类型,它实现了io.Readerio.Writer接口。该main()函数还调用该rand.Seed()函数以初始化随机数生成器。最后,for循环允许程序继续使用Accept()将由handleConnection()函数实例处理的新TCP客户端,这些实例作为goroutines执行。

net.Listen()的第一个参数

net.Listen()函数的第一个参数定义将使用的网络类型,而第二个参数定义服务器地址以及服务器将侦听的端口号。第一个参数的有效值为tcp,tcp4(仅限IPv4),tcp6(仅限IPv6),udp,udp4(仅限IPv4),udp6(仅限IPv6),ip,ip4(仅限IPv4),ip6(仅限IPv6),Unix(Unix套接字),Unixgram和Unixpacket。

并发TCP服务器正在运行

concTCP.go需要一个命令行参数,它是它将侦听的端口号。在为TCP客户端提供服务时,您将从concTCP.go获得的输出类似于以下内容:

$ go run concTCP.go 8001
Serving 127.0.0.1:62554
Serving 127.0.0.1:62556

输出netstat(1)可以验证concTCP.go在侦听更多连接时为多个TCP客户端提供服务:

$ netstat -anp TCP | grep 8001
tcp4       0      0  127.0.0.1.8001         127.0.0.1.62556        ESTABLISHED
tcp4       0      0  127.0.0.1.62556        127.0.0.1.8001         ESTABLISHED
tcp4       0      0  127.0.0.1.8001         127.0.0.1.62554        ESTABLISHED
tcp4       0      0  127.0.0.1.62554        127.0.0.1.8001         ESTABLISHED
tcp4       0      0  *.8001                 *.*                    LISTEN

上一个命令的输出的最后一行通知我们有一个进程侦听端口8001,这意味着您仍然可以连接到TCP端口8001.前两行验证是否存在已建立的TCP网络连接使用类似地,第三和第四行验证存在使用端口号8001和62554的另一个已建立的TCP连接。

此图显示了为多个TCP客户端提供服务时concTCP.go的输出:

6cb1b5798ac6899afeb179c7da337996.png
TCP功能于go_server.png

concTCP.go TCP服务器正在运行。

类似地,下图显示了使用该nc(1)实用程序实现的两个TCP客户端的输出:

35a4cafbd67b566ca3ced9492788d7cc.png
TCP功能于go_client.png

使用该nc(1)实用程序作为TCP客户端来concTCP.go。

你可以找到更多的信息nc(1),这也叫netcat(1),在维基百科上。

摘要

所以,您刚刚学会了如何使用大约65行Go代码开发一个生成随机数的并发TCP服务器,这非常令人印象深刻!如果您希望TCP服务器执行不同的工作,只需更改该handleConnection()功能的实现。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值