【问题标题】:Socket ReceiveAll套接字接收全部
【发布时间】:2016-09-04 08:06:25
【问题描述】:

我正在尝试在 c# 中捕获 ip 数据包。 一切正常,除了我只收到传出的数据包。

我的代码:

using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP))
{
    sock.Bind(new IPEndPoint(MYADDRESS, 0));
    sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
    sock.IOControl(IOControlCode.ReceiveAll, BitConverter.GetBytes(1), null);

    while (true)
    {
        byte[] buffer = new byte[sock.ReceiveBufferSize];
        int count = sock.Receive(buffer);

        // ...
    }
}

问题肯定是我的电脑!但也许有一种解决方法......

【问题讨论】:

  • 我还在寻找答案

标签: c# sockets


【解决方案1】:

Windows 防火墙可能正在阻止传入的数据包。将您的程序添加到防火墙排除项。

【讨论】:

    【解决方案2】:

    如果使用 WinPcap for .Net 和 SharpPcap (more info) 会怎样?

    它提供了一个 API,用于使用任何 .NET 语言(例如 C# 和 VB.NET)来捕获、注入、分析和构建数据包

    ....听起来更有希望

    【讨论】:

    • sry,我想自己写点东西,但如果我的代码没有解决方案,我可能会看看它
    • 自己编写一个非常适合练习和欣赏图书馆背后的巨大努力,当您使用它时,它可以满足您的需求。为了快速获得结果,该库是一个不错的选择
    • 没错,但正如你所说,我这样做是为了练习......所以我真的不需要一些快速的结果。
    【解决方案3】:

    我认为问题在于您正在绑定到环回 IP,假设您的代码中的“LOCALHOST”意味着 127.0.0.1。尝试绑定到要为其捕获数据包的接口的 IP 地址。

    我用你的代码做了一个快速测试,我肯定看到数据在两个方向流动,使用 Windows 7。NB我以管理员身份运行它,不知道它的工作情况如何。

      using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP))
      {
        sock.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.121"), 0));
    
        sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
    
        sock.IOControl(IOControlCode.ReceiveAll, BitConverter.GetBytes(1), null);
    
        while (true)
        {
          byte[] buffer = new byte[sock.ReceiveBufferSize];
    
          int count = sock.Receive(buffer);
          IpHeader hdr = IpHeader.FromPacket(buffer, count);
          if ((ProtocolType)hdr.Protocol == ProtocolType.Tcp)
          {
            Console.WriteLine("{0} : {1} -> {2}", (ProtocolType)hdr.Protocol, new IPAddress(hdr.SrcAddr).ToString(), new IPAddress(hdr.DestAddr).ToString());
          }
        }
      }
    

    IpHeader is from a library I wrote years ago,我用它来快速解码数据包,以确保我可以看到双向数据。

    这是从上面的代码中快速捕获以验证(AA.BB.CC.DD 是我的公共 IP)

    Tcp : 83.221.14.72 -> AA.BB.CC.DD
    Tcp : AA.BB.CC.DD -> 83.221.14.72
    Tcp : 83.221.14.72 -> AA.BB.CC.DD
    Tcp : 83.221.14.72 -> AA.BB.CC.DD
    Tcp : AA.BB.CC.DD -> 83.221.14.72
    Tcp : 83.221.14.72 -> AA.BB.CC.DD
    Tcp : 83.221.14.72 -> AA.BB.CC.DD
    Tcp : AA.BB.CC.DD -> 83.221.14.72
    Tcp : AA.BB.CC.DD -> 83.221.14.72
    Tcp : AA.BB.CC.DD -> 83.221.14.72
    Tcp : 83.221.14.72 -> AA.BB.CC.DD
    Tcp : 83.221.14.72 -> AA.BB.CC.DD
    Tcp : AA.BB.CC.DD -> 83.221.14.72
    

    【讨论】:

    • @rielz:那我肯定会把你的那个常量的名字改成LOCALHOST以外的其他名字
    • 我担心问题不是我的代码......但是像wireshark或ms网络监视器这样的嗅探器工作正常......所以它应该是可能的=/
    • 嗅探器使用内核模式驱动程序来实现这一点,这与原始套接字几乎不同。 WireShark 使用 WinPcap,Christian 提供了 .NET WinPCap 接口包装器的链接。
    • 程序以管理员权限运行,否则使用原始套接字会引发异常
    • 不,不.. 我的意思是程序在他们下运行以使用 SIO_RCVALL
    【解决方案4】:

    在我的情况下,我必须允许 windows 防火墙中的 vshost.exe

    【讨论】:

      【解决方案5】:

      我认为问题出在 IOControl 调用中。老实说,我不太了解MSDN 提供的有关此功能的文档,但codeproject (here) 中有一个关于此主题的示例,我的猜测是通过在最后一个参数中传递null 你不是获取传入的数据包。 试试这个:

      byte[] byTrue = new byte[4]{1, 0, 0, 0};
      byte[] byOut = new byte[4];
      
      sock.IOControl(IOControlCode.ReceiveAll, byTrue, byOut);
      

      【讨论】:

      • 已经试过了,不行(我认为这个字段会给你其他控制代码的数据)
      • @Christian,我也认为这可能是个问题,但我用它和 OPs 版本进行了测试,至少在我的机器上,两者都有效。
      • 他们在该页面的 cmets 中说原始套接字在 WinXP SP2 及更高版本中存在一些限制
      • 我的操作系统是 .net 4 的 win7 企业版
      猜你喜欢
      • 2021-06-20
      • 2020-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-01
      • 2012-03-08
      • 2023-03-30
      相关资源
      最近更新 更多