c - 接收自己发送的消息的原始套接字
问题描述
我试图使用原始套接字编写一些代码,同时观察到一些奇怪的现象。考虑代码:
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 address 绑定了一个套接字127.0.0.2
。当我打印发送方套接字的 IP 地址时,它正在打印,127.0.0.1
但它仍在接收用于127.0.0.2
. 当我添加评论部分中提到的连接请求时,这个问题得到了解决。这看起来很奇怪,因为另一方面,没有人接受或监听这个地址,而且,我正在使用sendto
和recvfrom
函数来发送和接收用于连接较少套接字的数据包。我的问题是,为什么会这样?这个连接请求如何解决这里的问题?
解决方案
现在,如果我 [不
connect()
使用套接字],我通过此 rsfd 发送的任何消息也会被自己接收。
我首先注意到原始套接字是 POSIX 的扩展。Linux 提供了它们,我认为其他系统也提供了,但它们的行为细节并不确定在不同的实现中是一致的。
话虽如此,问题似乎很可能是您没有bind()
将套接字连接到任何地址。例如,在 Linux 上,原始套接字的文档指出
bind(2)
可以使用调用 将原始套接字绑定到特定的本地地址 。如果未绑定,则接收所有具有指定 IP 协议的数据包。
(强调了。)在原始套接字具有这种行为的系统上,如果您通过既未绑定也未连接的原始 IP 套接字将数据包发送到 IP 环回地址,那么是的,源套接字将接收它们,或者至少可能会。
目前还不清楚为什么连接套接字可以解决问题,或者为什么它甚至完全成功。对于标准类型、、 和connect()
以外的套接字类型,未指定 的行为。但是,您观察到的行为与对原始套接字的影响是一致的,就像它对数据报套接字一样,它们也是无连接的:SOCK_DGRAM
SOCK_STREAM
SOCK_SEQPACKET
connect()
如果套接字
sockfd
类型为SOCK_DGRAM
,则addr
默认情况下数据报发送到的地址,也是接收数据报的唯一地址。
然而,我建议不要依赖于发现的行为,而是遵循记录的(至少在 Linux 上)将套接字绑定到地址(包括端口)的过程,并在该地址与它通信。
推荐阅读
- php - 将带大括号的字符串拆分为数组
- python - 在列表列表中查找最接近的匹配元素
- node.js - 在 cron 作业中运行节点脚本
- json - 如何修复 TypeError:req.url.toLowerCase 不是函数
- json - 响应有 JSON Parse 错误:Unrecognized token \'?\'
- java - 如何提高android中输入命令的速度?
- unity3d - 光线投射在运动物体上的准确性
- python - MovieWriter imagemagick 不可用
- php - 使用 PHP 和 SQL 在 highstock 烛台图表中未显示 JSON 数据
- c++ - 编译器生成的默认构造函数是否会将 std::array 中的指针初始化为 nullptr?