【问题标题】:Unable to read incoming responses using raw sockets无法使用原始套接字读取传入响应
【发布时间】:2011-01-30 03:07:15
【问题描述】:

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

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

【问题讨论】:

  • new IPEndPoint(localIP, 0) 指定要监听端口 0。是远程服务器连接的端口吗?
  • @RobertLevy - new IPEndPoint(localIP, 0) 指定您不关心您使用的本地端口。当(如果)您需要一个时,系统会选择一个。 (绑定、发送、接收……)对于设置了 ReceiveAll 的 RAW 套接字,您永远不需要一个,因为您正在接收所有内容。

标签: c# raw-sockets


【解决方案1】:

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

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

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

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

希望这会有所帮助:)

【讨论】:

  • 在有条件的情况下,我将字节数组转换为字符串,我已经能够轻松地将其与 Firebug 中的 Net 选项卡匹配。通过您建议的更改,我现在收到了一些传入流量,尽管我的程序仍然没有看到我在 Firebug 中看到的响应。我相信这是无连接的,尽管我昨天才开始研究套接字。
  • +1 谢谢!顺便说一句,你在 MSDN 上哪里找到了这些信息?
【解决方案2】:

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

我在 Win7 x64 下使用 VS2008 原生 C++ 构建。

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

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

【讨论】:

    【解决方案3】:

    今天我想知道如何做同样的事情!这是我的代码,现在似乎可以正常工作了,这要归功于回答者“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);
        }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 2020-02-22
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 2016-08-01
    • 2020-09-30
    相关资源
    最近更新 更多