Golang 网络编程丝绸之路 - TCP/UDP 地址解析
TL;DR 在使用 Golang 编写 TCP/UDP socket 的时候,第一步做的就是地址解析。
<ul><li>func ResolveTCPAddr(network, address string) (*TCPAddr, error)</li> <li> func ResolveUDPAddr(network, address string) (*UDPAddr, error)下面是对这两个函数的源码分析。</li> </ul><h2>ResolveTCPAddr</h2>
该函数返回的地址包含的信息如下:
<pre><code class="lang-go hljs">// src/net/tcpsock.go type TCPAddr struct { IP IP Port int Zone string // IPv6 scoped addressing zone } </code></code></pre>TCPAddr 里,<code>IP</code> 既可以是 IPv4 地址,也可以是 IPv6 地址。<code>Port</code> 就是端口了。<code>Zone</code> 是 IPv6 本地地址所在的区域。
从返回结果看该函数的参数,<code>network</code> 指 <code>address</code> 的网络类型;<code>address</code> 指要解析的地址,会从中解析出我们想要的 <code>IP</code>, <code>Port</code> 和 <code>Zone</code>。
从源码中可以看出,参数 <code>network</code> 只能是如下四个值,否则会得到一个错误。
<blockquote>默认解析器解析地址后返回一个地址列表 <code>addrs</code>,该地址列表既包含了 IPv4 地址,也包含了 IPv6 地址。
</blockquote> <ol><li>"": 将 <code>network</code> 置为 "tcp",这是因为在使用默认解析器对 <code>address</code> 进行解析时根据 <code>network</code> 返回 TCP 地址 <code>*TCPAddr</code>。</li> <li>"tcp": 若 <code>address</code> 是 IPv6 地址,则该函数返回 <code>addrs</code> 中的第一个 <code>IP</code> 是 IPv6 的地址,否则返回 <code>addrs</code> 中的第一个 <code>IP</code> 是 IPv4 的地址。</li> <li>"tcp4": 该函数返回 <code>addrs</code> 中的第一个 <code>IP</code> 是 IPv4 的地址。</li> <li>"tcp6": 该函数返回 <code>addrs</code> 中的第一个 <code>IP</code> 是 IPv6 的地址。</li> </ol><blockquote><code>addrs.forResolve</code> 相关源码如下:
</blockquote> <pre><code class="lang-go hljs">// src/net/ipsock.go // An addrList represents a list of network endpoint addresses. type addrList []Addr // isIPv4 reports whether addr contains an IPv4 address. func isIPv4(addr Addr) bool { switch addr := addr.(type) { case *TCPAddr: return addr.IP.To4() != nil ... } return false } // isNotIPv4 reports whether addr does not contain an IPv4 address. func isNotIPv4(addr Addr) bool { return !isIPv4(addr) } // forResolve returns the most appropriate address in address for // a call to ResolveTCPAddr, ResolveUDPAddr, or ResolveIPAddr. // IPv4 is preferred, unless addr contains an IPv6 literal. func (addrs addrList) forResolve(network, addr string) Addr { var want6 bool switch network { ... case "tcp", "udp": // IPv6 literal. (addr contains a port, so look for '[') want6 = count(addr, '[') > 0 } if want6 { return addrs.first(isNotIPv4) } return addrs.first(isIPv4) } // first returns the first address which satisfies strategy, or if // none do, then the first address of any kind. func (addrs addrList) first(strategy func(Addr) bool) Addr { for _, addr := range addrs { if strategy(addr) { return addr } } return addrs[0] } </code></code></pre> <h2>ResolveUDPAddr</h2>解析过程跟 ResolveTCPAddr 的一样,不过得到的是 <code>*UDPAddr</code>。
<code>UDPAddr</code> 包含的信息如下:
到此这篇关于“Golang 网络编程丝绸之路 - TCP/UDP 地址解析”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!
您可能感兴趣的文章:
Golang 网络编程丝绸之路 - TCP/UDP 地址解析
linux tcp文件分包_教你如何实现《UDP/TCP》可靠网络传输
socket套接字详解(TCP与UDP)
UDP是什么,UDP协议及优缺点
Java数据报编程之广播
电脑不能打开网页,但是QQ可以登陆
什么是MAC地址-基础知识
Golang基础第五篇——golang的gRPC
GoLang之网络
Go 语言的网络编程简介