在Go中构建并发TCP服务器
开发一个并发tcp服务器,该服务器仅使用大约65行go代码生成随机数。
tcp和udp服务器随处可见,通过tcp/ip网络为网络客户端提供服务。在本文中,我将在go编程语言,返回随机数。对于来自tcp客户端的每个传入连接,tcp服务器将启动一个新的goroutine来处理该请求。
你可以找到这个项目,conctcp.go,在github上。
处理tcp连接
程序的逻辑可以在handleconnection()职能,其实现方式如下:
func handleconnection(c net.conn) { fmt.printf("serving %s\n", 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() }
如果tcp客户端发送“stop”字符串,那么为该特定tcp客户端提供服务的goroutine将终止;否则,tcp服务器将向tcp客户端发送随机数。for循环确保tcp客户端将在tcp客户端所需的时间内得到服务。控件中的go代码。for循环从tcp客户端逐行读取数据,使用bufio.newreader(c).readstring('\n')并使用c.write([]byte(string(result)))。
兼容并蓄
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()call用于告诉go程序接受网络连接,从而充当服务器。的返回值net.listen()是net.conn类型,它实现io.reader和io.writer接口。main()函数还调用rand.seed()函数来初始化随机数生成器。最后,for循环允许程序继续接受新的tcp客户端。accept()的实例来处理handleconnection()函数,该函数作为goroutines执行。
net.listen()的第一个参数
的第一个参数net.listen()函数定义将要使用的网络类型,而第二个参数定义服务器地址以及服务器将侦听的端口号。第一个参数的有效值是tcp、tcp 4(仅ipv 4-)、tcp 6(仅ipv 6)、udp、udp 4(仅ipv 4-)、udp 6(仅ipv 6)、ip、ip4(仅ipv 4-)、ip6(仅ipv 6)、unix(unix套接字)、unixgram和unixpacket。
运行中的并发tcp服务器。
ctcp.go需要一个命令行参数,这是它要侦听的端口号。在为tcp客户端提供服务时,从ctcp.go获得的输出将类似于以下内容:
$ go run conctcp.go 8001 serving 127.0.0.1:62554 serving 127.0.0.1:62556
输出netstat(1)可以验证ctcp.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。前两行验证是否存在使用端口号8001和62556的已建立的tcp网络连接。类似地,第三行和第四行验证是否存在使用端口号8001和62554的另一个已建立的tcp连接。
下图显示了在为多个tcp客户端提供服务时,ctcp.go的输出:
ctcp.go tcp服务器正在运行。
类似地,下面的映像显示了两个tcp客户机的输出,它们使用nc(1)效用:
摘要
因此,您刚刚学习了如何开发一个并发tcp服务器,该服务器使用大约65行go代码生成随机数,这是相当令人印象深刻的!如果希望tcp服务器执行不同的任务,只需更改handleconnection()功能。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接
上一篇: 在Go中创建随机的安全密码
下一篇: Oracle排序中null值处理方法讲解