【问题标题】:Raw sockets receiving messages sent by itself接收自己发送的消息的原始套接字
【发布时间】:2019-04-04 13:54:29
【问题描述】:

我尝试使用原始套接字编写一些代码,同时观察到一些奇怪的现象。考虑代码:

                int rsfd = socket(AF_INET,SOCK_RAW,253);
                if(rsfd<0)
                {
                    perror("Raw socket not created");
                }
                else
                {
                    struct sockaddr_in addr2;
                    memset(&addr2,0,sizeof(addr2));
                    addr2.sin_family = AF_INET;
                    addr2.sin_addr.s_addr = inet_addr("127.0.0.2");
            /*       if(connect(rsfd,(struct sockaddr*)&addr2,sizeof(addr2))<0)
                    {
                        perror("Could not connect");continue;
                    } */
                }

现在,如果我删除注释部分,我通过此 rsfd 发送的任何消息也会被自己接收。在另一端,我已经绑定了一个 IP 地址为127.0.0.2 的套接字。当我打印发送方套接字的 IP 地址时,它正在打印127.0.0.1,但它仍在接收用于127.0.0.2 的数据包。当我添加评论部分中提到的连接请求时,这个问题得到了解决。这看起来很奇怪,因为另一方面,没有人接受或监听这个地址,而且,我正在使用 sendtorecvfrom 函数来发送和接收用于连接较少套接字的数据包。我的问题是,为什么会这样?这个连接请求如何解决这里的问题?

【问题讨论】:

    标签: c sockets networking raw-sockets


    【解决方案1】:

    现在,如果我 [不connect() 套接字],我通过这个 rsfd 发送的任何消息也会被它自己接收。

    我首先注意到原始套接字是对 POSIX 的扩展。 Linux 提供了它们,我认为其他系统也提供了,但它们的行为细节并不确定在不同的实现中是一致的。

    话虽如此,问题似乎是您没有bind()将您的套接字发送到任何地址。例如,在 Linux 上,the docs for raw sockets 请注意

    原始套接字可以使用 bind(2) 打电话。 如果不绑定,则所有指定IP的包 收到协议。

    (已添加重点。)在原始套接字具有该行为的系统上,如果您通过既未绑定也未连接的原始 IP 套接字将数据包发送到 IP 环回地址,那么是的,源套接字将接收它们,或者至少可以。

    目前还不清楚为什么连接套接字可以解决问题,或者为什么它甚至完全成功。 connect() 的行为对于标准类型之外的套接字类型,SOCK_DGRAMSOCK_STREAMSOCK_SEQPACKET 未指定。但是,您观察到的行为与 connect() 对原始套接字的影响是一致的,就像它对数据报套接字一样,它们也是无连接的:

    如果套接字sockfd的类型是SOCK_DGRAM,那么addr就是地址 数据报默认发送到哪个地址,以及唯一的地址来自 接收到哪些数据报。

    不过,我建议不要依赖已发现的行为,而是遵循文档中的(至少在 Linux 上)将套接字绑定到地址(包括端口)并在该地址与其通信的过程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-21
      相关资源
      最近更新 更多