如何用Go语言编写代码实现发送和接收原始Socket数据包,并构造IP和TCP头部信息?

2026-05-08 00:401阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计942个文字,预计阅读时间需要4分钟。

如何用Go语言编写代码实现发送和接收原始Socket数据包,并构造IP和TCP头部信息?

在Linux/macOS系统中,非root用户默认无法创建raw socket,这是内核的强制限制,而非Go语言的bug。即使使用了`syscall.SOCK_RAW`和`syscall.IPPROTO_RAW`,在创建socket时也会因为权限不足(`EPERM`)而失败。

  • 临时解决:用 sudo go run main.go(开发调试可用,但别上线)
  • 生产环境更稳妥的方式是给二进制加 CAP_NET_RAW 能力:sudo setcap cap_net_raw+ep ./myprogram,之后普通用户就能运行
  • macOS 还需额外注意:IPPROTO_RAW 不被支持,得用 IPPROTO_TCP + IP_HDRINCL 选项绕过,否则 setsockopt 会失败

syscall.SetsockoptInt 设置 IP_HDRINCL 没生效,发出去的包被内核重写 IP 头

没生效通常是因为调用时机错了——必须在 bind 之前设置,且 socket 类型得是 AF_INET + SOCK_RAW + IPPROTO_RAW(Linux)或 IPPROTO_TCP(macOS)。

阅读全文

本文共计942个文字,预计阅读时间需要4分钟。

如何用Go语言编写代码实现发送和接收原始Socket数据包,并构造IP和TCP头部信息?

在Linux/macOS系统中,非root用户默认无法创建raw socket,这是内核的强制限制,而非Go语言的bug。即使使用了`syscall.SOCK_RAW`和`syscall.IPPROTO_RAW`,在创建socket时也会因为权限不足(`EPERM`)而失败。

  • 临时解决:用 sudo go run main.go(开发调试可用,但别上线)
  • 生产环境更稳妥的方式是给二进制加 CAP_NET_RAW 能力:sudo setcap cap_net_raw+ep ./myprogram,之后普通用户就能运行
  • macOS 还需额外注意:IPPROTO_RAW 不被支持,得用 IPPROTO_TCP + IP_HDRINCL 选项绕过,否则 setsockopt 会失败

syscall.SetsockoptInt 设置 IP_HDRINCL 没生效,发出去的包被内核重写 IP 头

没生效通常是因为调用时机错了——必须在 bind 之前设置,且 socket 类型得是 AF_INET + SOCK_RAW + IPPROTO_RAW(Linux)或 IPPROTO_TCP(macOS)。

阅读全文