关于使用C# Raw Socket发送手动构造ARP回复的技术咨询
嘿,能手动构造ARP包来学习,这绝对是深入掌握网络协议和Raw Socket的好路子!我当初学这个的时候也踩了不少坑,给你几个关键的提醒,帮你顺利把ARP回复发出去:
1. 必须以管理员身份运行程序
Windows系统对Raw Socket的权限限制很严,普通用户权限创建ProtocolType.Raw的套接字会直接抛出SocketException(错误码10013)。所以一定要右键你的项目,选择“以管理员身份运行”,或者在VS里设置调试时的管理员权限。
2. 检查ARP包的构造是否完整
你手动写的字节数组得确保以太网帧头和ARP报文的每个字段都准确,不然发出去的包也是无效的:
- 以太网帧头:前6字节是目标MAC(ARP回复要发给请求的主机,所以填对方的MAC),接下来6字节是你的网卡MAC,然后2字节是以太网类型,ARP固定是
0x0806 - ARP报文部分:
- 硬件类型
0x0001(以太网)、协议类型0x0800(IPv4) - 硬件地址长度
0x06、协议地址长度0x04 - 操作码
0x0002(这是ARP回复,请求是0x0001) - 然后依次是你的MAC、你的IP、目标MAC、目标IP
- 硬件类型
3. 绑定到特定网卡(可选但推荐)
如果你的机器有多张网卡,最好把Socket绑定到你要发送ARP包的那张网卡的IP上,避免系统自动选到错误的网卡:
socket.Bind(new IPEndPoint(IPAddress.Parse("你的本地IP"), 0));
完善后的示例代码
结合上面的点,给你补全一下代码,方便你测试:
using System; using System.Net; using System.Net.Sockets; class ArpSender { static void Main(string[] args) { // 创建原始套接字 using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Raw); // 构造ARP回复包(替换成你实际的MAC和IP) byte[] buffer = new byte[] { // 以太网帧头 0x34, 0x97, 0xf6, 0x22, 0x04, 0xe8, // 目标MAC:请求ARP的主机MAC 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // 源MAC:你的网卡MAC 0x08, 0x06, // 以太网类型:ARP // ARP报文 0x00, 0x01, // 硬件类型:以太网 0x08, 0x00, // 协议类型:IPv4 0x06, // 硬件地址长度 0x04, // 协议地址长度 0x00, 0x02, // 操作码:ARP回复 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, // 发送端MAC(你的MAC) 0xc0, 0xa8, 0x01, 0x02, // 发送端IP(比如192.168.1.2) 0x34, 0x97, 0xf6, 0x22, 0x04, 0xe8, // 目标MAC(请求方MAC) 0xc0, 0xa8, 0x01, 0x01 // 目标IP(请求方IP,比如192.168.1.1) }; try { // 绑定到本地网卡IP socket.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.2"), 0)); int bytesSent = socket.Send(buffer, buffer.Length, SocketFlags.None); Console.WriteLine($"成功发送 {bytesSent} 字节的ARP回复!"); } catch (SocketException ex) { Console.WriteLine($"发送失败:{ex.Message},错误码:{ex.ErrorCode}"); if (ex.ErrorCode == 10013) { Console.WriteLine("划重点:请以管理员身份运行程序!"); } } // using语句会自动释放Socket,不用手动Close } }
额外提醒
- 测试的时候可以用Wireshark抓包,看看发出去的ARP包是否正确
- 有些杀毒软件或者防火墙会拦截Raw Socket的流量,测试时可以暂时关闭或者添加例外
内容的提问来源于stack exchange,提问作者Joas
相关产品推荐
相关产品推荐

