原始套接字接收自己发送的消息

问题描述 投票:0回答:1

我试图使用原始套接字编写一些代码,而我发现了一些奇怪的现象。考虑一下代码:

                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个回答
1
投票

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

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

话虽如此,问题似乎可能是你不是bind()ing你的套接字到任何地址。例如,在Linux上,the docs for raw sockets会注意到这一点

可以使用bind(2)调用将原始套接字绑定到特定的本地地址。如果未绑定,则接收具有指定IP协议的所有数据包。

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

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

如果套接字sockfd的类型为SOCK_DGRAM,那么addr是默认发送数据报的地址,也是接收数据报的唯一地址。

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

© www.soinside.com 2019 - 2024. All rights reserved.