我试图通过监听原始套接字来读取网站上的响应,但到目前为止我只能读取我的计算机发送的传出请求,而不是我实际上的传入响应有兴趣。 我怎样才能阅读传入的回复?
编辑:使用Wireshark我相信我发现我正在寻找的数据是通过TCP发送的。我相信。
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Unspecified);
IPAddress localIP = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
listener.Bind(new IPEndPoint(localIP, 0));
byte[] invalue = new byte[4] { 1, 0, 0, 0 };
byte[] outvalue = new byte[4] { 1, 0, 0, 0 };
listener.IOControl(IOControlCode.ReceiveAll, invalue, outvalue);
while (true)
{
byte[] buffer = new byte[1000000];
int read = listener.Receive(buffer);
if (read >= 20)
{
Console.WriteLine("Packet from {0} to {1}, protocol {2}, size {3}",
new IPAddress((long)BitConverter.ToUInt32(buffer, 12)),
new IPAddress((long)BitConverter.ToUInt32(buffer, 16)),
buffer[9],
buffer[2] << 8 | buffer[3]
);
}
}
答案 0 :(得分:6)
端口0说他会监听所有端口,我认为你需要将ProtocolType.Unspecified设置为ProtocolType.IP。
new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Raw);
是我从msdn上读到的ipv6,只有带有原始套接字的ipv4的ProtocolType.IP。
另外我觉得这是一个无连接插座吧? 除非是这样,否则Reciveall不会产生任何影响。 如果您在ip标题之后,您可以通过设置如下代码来获取它:
Socket sck = new Socket( AddressFamily.InterNetwork , SocketType.Raw , ProtocolType.IP);
sck.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
希望这有助于:)
答案 1 :(得分:1)
我的C ++程序中存在类似的问题,使用的是基本相同的原始套接字设置。在我的情况下,我可以在调试版本中看到传入的数据包,但不能在发布版本中看到。在两个版本中都可以看到传出的数据包。我不是在这个程序中发送任何数据包。
我正在使用Win7 x64下的VS2008本机C ++构建。
我的问题出在防火墙上。当项目在VS中创建时,它显然在防火墙中放置了一个“允许”条目,用于项目构建的网络访问,但仅用于程序的调试版本。
我必须为发布版本添加另一个条目,然后允许传入的数据包。 Win7下的高级防火墙设置也会导致特定协议被阻止,因此如果您只获得部分传入消息,请检查该程序的条目设置。
答案 2 :(得分:1)
今天我想知道如何做同样的事情!这是我的代码,现在似乎工作,因为得到这个工作是由于回答者'汤姆埃里克'建议ProtocolType.IP。
static void Main(string[] args)
{
// Receive some arbitrary incoming IP traffic to an IPV4 address on your network adapter using the raw socket - requires admin privileges
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
IPAddress ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList
.Where((addr) => addr.AddressFamily == AddressFamily.InterNetwork)
.Where((addr) => addr.GetAddressBytes()[0] != 127)
.First();
s.Bind(new IPEndPoint(ipAddress, 0));
byte[] b = new byte[2000];
EndPoint sender = new IPEndPoint(0, 0);
int nr = s.ReceiveFrom(b, SocketFlags.None, ref sender);
}