- 前言
- Go 与操作系统
- Go 内部机制
- Go 基本数据类型
- 4 组合类型的使用
- 5 数据结构
- 6 Go package 中不为人知的知识
- 7 反射和接口
- 8 Go UNIX 系统编程
- 08.1 关于 UNIX 进程
- 08.2 flag 包
- 8.2 flag 包
- 08.3 io.Reader 和 io.Writer 接口
- 08.4 bufio 包
- 08.5 读取文本文件
- 08.6 从文件中读取所需的数据量
- 08.7 为什么我们使用二进制格式
- 08.8 读取 CSV 文件
- 08.9 写入文件
- 08.10 从磁盘加载和保存数据
- 08.11 再看strings包
- 08.12 关于bytes包
- 08.13 文件权限
- 08.14 处理 Unix 信号
- 08.15 Unix 管道编程
- 08.16 遍历目录树
- 08.17 使用 ePBF
- 08.18 关于 syscall.PtraceRegs
- 08.19 跟踪系统调用
- 08.20 User ID 和 group ID
- 08.21 其他资源
- 08.22 练习
- 08.23 总结
- 9 并发 Goroutines、Channel 和 Pipeline
- 10 Go 并发-进阶讨论
- 11 代码测试、优化及分析
- 12 Go 网络编程基础
- 13 网络编程 - 构建服务器与客户端
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
13.8 底层网络编程
虽然 http.Transport
结构允许您修改网络连接的底层参数,但您可以编写允许您读取网络包原始数据的 Go 代码。这有两个棘手的问题:
- 网络包采用二进制格式,这要求您查找特定类型的网络数据包,而不仅仅是任何类型的网络数据包。
- 为了发送一个网络数据包,您必须自己构建。
接下来要展示的是 lowLevel.go
,并把它分为三个部分。注意 lowLevel.go
捕获 ICMP 数据包,使用 IPv4 协议并打印包的内容。另外,由于安全原因操作原始网络数据需求 root 权限。
lowLevel.go
的第一段如下:
package main
import(
"fmt"
"net"
)
lowLevel.go
的第二段代码如下:
func main() {
netaddr, err := net.ResolveIPAddr("ip4", "127.0.0.1")
if err != nil {
fmt.Println(err)
return
}
conn, err := net.ListenIP("ip4:icmp", netaddr)
if err != nil {
fmt.Println(err)
return
}
ICMP 协协议被定义在 net.ListenIP()
函数的第一个参数的第二部分。此外,ip4
部分告诉程序只捕获 IPv4 流量。
lowLevel.go
的其余 Go 代码如下:
buffer := make([]byte, 1024)
n, _, err := conn.ReadFrom(buffer)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("% X\n", buffer[0:n])
}
上面这段代码告诉 lowLevel.go
只读取一个网络包,因为没有 for
循环。
ICMP 协议由 ping(1)
和 traceroute(1)
命令使用,所以为了产生 ICMP 流量,可以使用它们中的任何一个。当 lowLevel.go
已经运行后,在所有的 Unix 机器上使用如下命令就会产生 ICMP 网络流量。
$ ping -c 5 localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.037 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.038 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.117 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.052 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.049 ms
--- localhost ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.037/0.059/0.117/0.030 ms
$ traceroute localhost
traceroute to localhost (127.0.0.1), 64 hops max, 52 byte packets
1 localhost(127.0.0.1) 0.255 ms 0.048 ms 0.067 ms
在 macOS High Sierra 机器上用 root 权限执行 lowLevel.go
将产生如下输出:
$ sudo go run lowlevel.go
03 03 CD DA 00 00 00 00 45 00 34 00 B4 0F 00 00 01 00 00 7F 00 00 01 7F 00 00 01 B4 0E 82 9B 00 20 00 00
$ sudo go run lowLevel.go
00 00 0B 3B 20 34 00 00 5A CB 5C 15 00 04 32 A9 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37
第一个输出的例子是 ping(1)
命令产生的,第二个是 traceroute(1)
命令产生的。
在 Debian Linux 机器上运行 lowLevel.go
将产生如下输出:
$ uname -a
Linux mail 4.14.12-x86_64-linode92 #1 SMP Fri Jan 5 15:34:44 UTC 2018 x86_64 GNU/Linux
# go run lowLevel.go
08 00 61 DD 3F BA 00 01 9A 5D CB 5A 00 00 00 00 26 DC 0B 00 00 00 00 00 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37
# go run lowLevel.go
03 03 BB B8 00 00 00 00 45 00 00 3C CD 8D 00 00 01 11 EE 21 7F 00 00 01 7F 00 00 01 CB 40 82 9A 00 28 FE 3B 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
uname(1)
命令打印出 Linux 系统的有用信息。注意,在当前的 Linux 机器上,您应该在执行 ping(1)
命令时使用 -4 标志来告诉它使用 IPv4 协议。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论