TCP 和 UDP 服务端随处可见,它们基于 TCP/IP 协议栈,通过网络为客户端提供服务。在这篇文章中,我将介绍如何使用 Go 语言开发一个用于返回随机数、支持并发的 TCP 服务端。对于每一个来自 TCP 客户端的连接,它都会启动一个新的 goroutine(轻量级线程)来处理相应的请求。
创新互联企业建站,十多年网站建设经验,专注于网站建设技术,精于网页设计,有多年建站和网站代运营经验,设计师为客户打造网络企业风格,提供周到的建站售前咨询和贴心的售后服务。对于网站建设、成都网站设计中不同领域进行深入了解和探索,创新互联在网站建设中充分了解客户行业的需求,以灵动的思维在网页中充分展现,通过对客户行业精准市场调研,为客户提供的解决方案。
你可以在 GitHub 上找到本项目的源码:concTcp.go。
这个程序的主要逻辑在 handleConnection 函数中,具体实现如下:
在 main 函数的实现部分,每当 TCP 服务端收到 TCP 客户端的连接请求,它都会启动一个新的 goroutine 来为这个请求提供服务。
首先, main 确保程序至少有一个命令行参数。注意,现有代码并没有检查这个参数是否为有效的 TCP 端口号。不过,如果它是一个无效的 TCP 端口号, net.Listen 就会调用失败,并返回一个错误信息,类似下面这样:
net.Listen 函数用于告诉 Go 接受网络连接,因而承担了服务端的角色。它的返回值类型是 net.Conn ,后者实现了 io.Reader 和 io.Writer 接口。此外, main 函数中还调用了 rand.Seed 函数,用于初始化随机数生成器。最后, for 循环允许程序一直使用 Accept 函数来接受 TCP 客户端的连接请求,并以 goroutine 的方式来运行 handleConnection(c) 函数,处理客户端的后续请求。
net.Listen 函数的第一个参数定义了使用的网络类型,而第二个参数定义了服务端监听的地址和端口号。第一个参数的有效值为 tcp 、 tcp4 、 tcp6 、 udp 、 udp4 、 udp6 、 ip 、 ip4 、 ip6 、 Unix (Unix 套接字)、 Unixgram 和 Unixpacket ,其中: tcp4 、 udp4 和 ip4 只接受 IPv4 地址,而 tcp6 、 udp6 和 ip6 只接受 IPv6 地址。
concTCP.go 需要一个命令行参数,来指定监听的端口号。当它开始服务 TCP 客户端时,你会得到类似下面的输出:
netstat 的输出可以确认 congTCP.go 正在为多个 TCP 客户端提供服务,并且仍在继续监听建立连接的请求:
在上面输出中,最后一行显示了有一个进程正在监听 8001 端口,这意味着你可以继续连接 TCP 的 8001 端口。第一行和第二行显示了有一个已建立的 TCP 网络连接,它占用了 8001 和 62556 端口。相似地,第三行和第四行显示了有另一个已建立的 TCP 连接,它占用了 8001 和 62554 端口。
下面这张图片显示了 concTCP.go 在服务多个 TCP 客户端时的输出:
类似地,下面这张图片显示了两个 TCP 客户端的输出(使用了 nc 工具):
你可以在 维基百科上找到更多关于 nc (即 netcat )的信息。
现在,你学会了如何用大约 65 行 Go 代码来开发一个生成随机数、支持并发的 TCP 服务端,这真是太棒了!如果你想要让你的 TCP 服务端执行别的任务,只需要修改 handleConnection 函数即可。
via:
作者:Mihalis Tsoukalos选题:lkxed译者:lkxed校对:wxy
安装:
go get -v -u github.com/rocket049/connpool
go get -v -u gitee.com/rocket049/connpool
rocket049/connpool 包是本人用go语言开发的,提供一个通用的TCP连接池,初始化参数包括最高连接数、超时秒数、连接函数,放回连接池的连接被重新取出时,如果已经超时,将会自动重新连接;如果没有超时,连接将被复用。
可调用的函数:
调用示例:
TL;DR 在使用 Golang 编写 TCP/UDP socket 的时候,第一步做的就是地址解析。
该函数返回的地址包含的信息如下:
TCPAddr 里, IP 既可以是 IPv4 地址,也可以是 IPv6 地址。 Port 就是端口了。 Zone 是 IPv6 本地地址所在的区域。
从返回结果看该函数的参数, network 指 address 的网络类型; address 指要解析的地址,会从中解析出我们想要的 IP , Port 和 Zone 。
从源码中可以看出,参数 network 只能是如下四个值,否则会得到一个错误。
解析过程跟 ResolveTCPAddr 的一样,不过得到的是 *UDPAddr 。
UDPAddr 包含的信息如下: