【笔记】GO编程中IP地址及端口号变量不同类型的相互转化
最近在学习写一个基于SOCKS5协议的代理服务器,过程中频繁用到各种IP地址和端口号数据类型的相互转换,比如net.TCPAddr、string字符串型的“127.0.0.1:8080”、[]byte切片型、int型,非常混乱。特在这里做个总结备忘,第一篇博客,就献给这一问题吧!
一、格式种类
我们在GO网路编程中,常用的IP地址和端口号,大概有一下三种。
(1)net.TCPAddr(IP/UDP)
定义在net包中。在我们调用listen、dial等函数时,输入的参数就是这种格式,它的定义是:
type TCPAddr struct {
IP IP //其中:type IP []byte
Port int
Zone string // IPv6 scoped addressing zone
}
p.s.
func IPv4(a, b, c, d byte) IP {
p := make(IP, IPv6len)
copy(p, v4InV6Prefix)
p[12] = a
p[13] = b
p[14] = c
p[15] = d
return p
}
(2)string型"127.0.0.1:8080"
在两个函数之间传值,推荐转化成这种格式传值。千万要杜绝使用[]byte传值,因为[]byte对应的底层数组没有变
(3)[]byte切片
手动构造数据包内容的时候,会用到它。另外,IP是[]byte格式
二、转换方法
1、net.TCPAddr(IP/UDP)转string字符串
方法:调用net.XXXAddr的String()方法
示例:
a:=net.TCPAddr{}
b:=a.String()
2、string字符串转net.TCPAddr(IP/UDP)
方法:调用net包的net.ResolveTCPAddr(ResolveIPAddr/ResolveUDPAddr)
示例:
a:="127.0.0.1:8080"
b, err := net.ResolveTCPAddr("tcp", a)
3、string类型地址字符串IP与port的分割(“127.0.0.1:8080”->“127.0.0.1”,“8080”)
方法:调用net包的net.SplitHostPort()
示例:
a:="127.0.0.1:8080"
ip, port, err := net.SplitHostPort(a)
4、int型端口号转[]byte切片
方法:现将int型转int64,再用strconv.FormatInt()、hex.DecodeString()转
示例:
port_int:=8080
port_byte, err := hex.DecodeString(strconv.FormatInt(int64(port_int), 16))
5、string字符串转[]byte切片
方法:先将"127.0.0.1:8080"切割成为->“127.0.0.1”,“8080”,然后分别转[]byte
示例:
a:="127.0.0.1:8080"
ip, port, err := net.SplitHostPort(a)
ip_byte := []byte(net.ParseIP(ip_str).To4())
p, err := strconv.Atoi(p_str)
p_byte := make([]byte, 2)
binary.BigEndian.PutUint16(p_byte, uint16(p))
6、[]byte切片转string字符串
方法:同上,分别转换
示例:
ip_byte:=[]byte
port_byte:=[]byte
var ip_str string
if ip_byte是网址 {
ip_str = bytes.NewBuffer(ip_byte).String()
} else {ip_byte是IP
ip_str = net.IP(ip_byte).String()
}
port_str := strconv.Itoa(int(binary.BigEndian.Uint16(r.DstPort)))
addr:=net.JoinHostPort(s, p)