使用C#发送TCP数据包

3
我希望能在C#中发送一个TCP数据包(自定义标头)。构建这样的数据包并不是问题,我已经将数据存储在一个字节数组中。但是我该如何通过套接字发送这个数据包呢?
我尝试了类似以下的方法:
using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP))
{
    TcpPacket tcpPacket = new TcpPacket();
    // fill tcpPacket with data
    sock.Bind(new IPEndPoint(MYADDRESS, MYPORT));
    byte[] data = tcpPacket.GetBytes();
    sock.SendTo(data, new IPEndPoint(DESTADDRESS, DESTPORT));
}

这段代码没有出现任何异常,但是网络嗅探显示没有发送任何内容。有什么解决方法吗?
我使用的是Windows 7专业版,不想让系统自己创建完整的TCP连接。
PS:我不想使用其他库。
PS:构建IP数据包也不是问题。

SocketType.Raw: [...] 当发送数据时,您的应用程序必须提供完整的IP头。[...] 您尝试在数据包中包含完整的IP头吗? - dtb
错过了。我将尝试使用完整的IP头部进行操作,谢谢。 - ordag
尝试了一遍,但仍然没有发出任何数据包 :( - ordag
抱歉因为格式混乱,我不确定发生了什么 - Bobby
@Bobby:哦,不是你的错,没事 :) - ordag
6个回答

3

如果您想在Windows 7上发送自己创建的TCP数据包,您需要像WinPcap这样的驱动程序。如果您使用WinPcap,您可以使用许多.NET包装器或编写自己的代码。仅使用Windows API提供的对象(例如套接字)发送原始帧将无法正常工作。

只需查看TCP/IP Raw Sockets

唯一的替代方案是创建自己的网络监视驱动程序,或购买商业版的WinPcap,它不需要安装,但可以完美地集成到您的程序中。

在Windows 7、Windows Vista、Windows XP Service Pack 2(SP2)和Windows XP Service Pack 3(SP3)上,通过原始套接字发送流量的能力已被多种方式限制:

不能通过原始套接字发送TCP数据。

如果您改变主意了,也许您可以在eExNetworkLibrary中找到需要的东西。
它包含一个WinPcap封装程序和许多用于创建和分析数据包的方法和对象。希望这对您有用。

1
你是想发送TCP数据包还是UDP数据包?如果你想发送TCP数据包,你需要在尝试发送数据包之前使用Connect()连接到远程端点。

这是我的问题。我想用自定义数据包自己打开连接 =/ - ordag
你可以自己打开连接,只需在 sock 对象上调用 Connect 方法即可。我觉得你这里缺少了一行代码,就是这样。 - CodingGorilla
如果我将套接字Connect()到一个关闭的端口,我会收到一个异常,但我想读取Ack-Rst-Packet。 - ordag

1

是的,正如您在http://www.csharp-examples.net/socket-send-receive/中看到的那样,您可以访问基础套接字。附注:使用此功能进行创建:http://msdn.microsoft.com/en-us/library/3bsb3c8f.aspx,并连接http://msdn.microsoft.com/en-us/library/d6kc0793.aspx。 - basarat
但是Connect()方法会打开完整的连接,对吗? - ordag
是的,它打开了一个完整的连接。 - basarat
那么这不是我要找的,抱歉我应该更准确地描述我的问题,但谢谢。 - ordag
我明白。这只能通过某些pcap衍生产品来完成。因此,这是我的第二个答案。 - basarat

1

你正在绑定你的套接字,但你应该Connect()(到另一个端点)。


我不想让系统自己创建连接 :( - ordag

1

抱歉,不想依赖于pcap,希望能有另一种解决方案=/ - ordag

0

你应该使用SocketType.Stream

SocketType.Raw:支持访问底层传输协议。使用SocketTypeRaw,您可以使用诸如Internet控制消息协议(Icmp)和Internet组管理协议(Igmp)之类的协议进行通信。发送时,您的应用程序必须提供完整的IP头。接收到的数据报返回时保留IP头和选项。

SocketType.Stream:支持可靠的、双向的、基于连接的字节流,不会重复数据,也不会保留边界。此类型的Socket与单个对等方通信,并在通信开始之前需要远程主机连接。Stream使用传输控制协议(Tcp)ProtocolType和InterNetworkAddressFamily。


在 Steam 中,我是否对每个数据包都有完全的控制权? - ordag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接