3

我试图通过侦听原始套接字通过代码从网站读取响应,但到目前为止,我只能读取我的计算机发送的传出请求,而不是我真正感兴趣的传入响应。我该如何阅读收到的回复?

编辑:使用 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]
        );
    }
}
4

3 回答 3

6

端口 0 表示他将监听所有端口,我认为您需要将 ProtocolType.Unspecified 设置为 ProtocolType.IP 。

new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Raw); 用于 ipv6,从我在 msdn 上阅读的内容来看,只有带有原始套接字的 ipv4 支持 ProtocolType.IP。

我也认为这是一个无连接的套接字,对吗?除非情况如此,否则 Reciveall 不会真正产生影响。如果您在 ip 标头之后,您可以通过设置如下代码来获取它:

Socket sck = new Socket( AddressFamily.InterNetwork  , SocketType.Raw  , ProtocolType.IP);
   sck.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);  

希望这可以帮助 :)

于 2011-01-30T12:51:57.420 回答
1

我在使用基本相同的原始套接字设置的 C++ 程序中遇到了类似的问题。就我而言,我可以在调试版本中看到传入的数据包,但在发布版本中看不到。在两个版本中都可以看到传出的数据包。我没有在这个程序中发送任何数据包。

我在 Win7 x64 下使用 VS2008 本机 C++ 构建。

我的问题是防火墙。当在 VS 中创建项目时,它显然在防火墙中放置了一个“允许”条目,以供项目构建进行网络访问,但仅用于程序的调试构建。

我必须为发布版本添加另一个条目,然后允许传入数据包。Win7 下的高级防火墙设置也可能导致特定协议被阻止,因此如果您只收到部分传入消息,请检查这些设置以获取程序条目。

于 2011-02-26T15:33:41.600 回答
1

今天我想知道如何做同样的事情!这是我的代码,现在似乎可以工作了,这要归功于回答者“Tom Erik”建议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);
    }
于 2012-09-06T23:22:57.467 回答