相同的BSD套接字API程序在Python中工作,但在C++;还是生锈

相同的BSD套接字API程序在Python中工作,但在C++;还是生锈,python,c++,c,sockets,rust,Python,C++,C,Sockets,Rust,我一直在尝试从我的Yeelight智能灯泡收听多播UDP消息。灯泡定期在IP上广播其存在239.255.255.250port1982。此外,当在同一IP和端口上发送特定请求()时,灯泡将响应 使用套接字,我试图建立通信。在两台机器(MaOS和Linux)上,下面所示的Python程序运行在RepWorkWork上,但是RISC代码和C++代码也显示在下面(基本上做同样的事情)。Rust程序似乎两次成功接收0字节,然后挂起等待。在C++程序中,ReV函数刚刚挂起,永远不会返回。 有什么问题吗?为

我一直在尝试从我的Yeelight智能灯泡收听多播UDP消息。灯泡定期在IP上广播其存在
239.255.255.250
port
1982
。此外,当在同一IP和端口上发送特定请求()时,灯泡将响应

使用套接字,我试图建立通信。在两台机器(MaOS和Linux)上,下面所示的Python程序运行在RepWorkWork上,但是RISC代码和C++代码也显示在下面(基本上做同样的事情)。Rust程序似乎两次成功接收0字节,然后挂起等待。在C++程序中,ReV函数刚刚挂起,永远不会返回。 有什么问题吗?为什么只有Python才能成功通信

将套接字作为
导入结构
sock=s.socket(s.AF_INET、s.sock_DGRAM、s.IPPROTO_UDP)
sock.setsockopt(s.IPPROTO_IP,s.IP_ADD_MEMBERSHIP,struct.pack(“4sL”,s.inet_aton(“239.255.255.250”),s.INADDR_ANY))
sock.sendto(“M-SEARCH*HTTP/1.1\r\n主机:239.255.255.250:1982\r\n主机:ssdp:discover\”\r\nST:wifi\u bulb\r\n.encode('UTF-8'),('239.255.255.250',1982))
sock.recv(4096)#在第一次呼叫时立即成功接收到消息
#[macro_use]外部板条箱日志;
使用socket2::{Socket,域,类型,协议,SockAddr};
使用std::net:{SocketAddrV4,Ipv4Addr};
fn main(){
环境记录器::init();
let Yelight_ip=Ipv4Addr::new(239255525250);
让我们来关注一下港口:u16=1982;
让套接字=套接字::新建(
域::ipv4(),
类型::dgram(),
一些(协议::udp()
).expect(“创建套接字失败!”);
socket.join\u多播\u v4(
&叶澍鹖,
&Ipv4Addr::未指定
).expect(“无法加入多播广播!”);
let msg=“M-SEARCH*HTTP/1.1\r\n主机:239.255.255.250:1982\r\n主机名:\“ssdp:discover\”\r\nST:wifi\r\n”;
匹配套接字。将\u发送到(
msg.as_bytes(),
&SockAddr::来自(
SocketAddrV4::新建(
叶澍鹖,
耶利港
)
)
) {
正常(已发送字节)=>{
//一些调试打印行
},
Err()=>eprintln!(“错误广播标识请求!”)
环路{
让mut buffer=Vec::具有_容量(1024*1024);
让接收的字节数=套接字
.recv(&mut缓冲区)
.expect(“无法接收邮件!”);
调试!(“接收的{}字节”,接收的_字节);
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
const std::string msg=“M-SEARCH*HTTP/1.1\r\n主机:239.255.255.250:1982\r\n主机名:\“ssdp:discover\”\r\nST:wifi\r\n”;
int main(){
auto yeelight_ip=in_addr();
inet_aton(“239.255.255.250”和Yeellight_ip);
无符号int yeelight_端口=1982;
自动插接=插接(自动插接、插接内存、IP协议);

由于Python在幕后很好地实现了转换,因此Python程序按预期工作

C(++)程序无法运行,因为端口的结尾错误。我忘记了我必须使用
addr.sin_port=htons(yelight_port);


至于Rust程序,我忘记了
with_capacity
只分配了内部缓冲区,但是
Vec
仍然是空的。描述的解决方案是调用
buffer.resize(buffer.capacity(),0);

你的Rust程序在循环中接收:你的Swift程序接收一次。它们不是等价的。当你在Rust代码中打开接收到的缓冲区时,你忽略了消息长度。我看不出这些是如何被视为问题的。Python立即接收,而Rust没有在循环中接收,这一事实更值得关注另外,我忽略的消息长度是多少?
String::from_utf8(缓冲区)
忽略
已接收字节的值。
我看不出在循环中读取是如何失败的。循环只能在您确实接收到某个内容的情况下进行迭代,并且未能正确使用长度足以说明您认为已接收到0个字节。如果您查看上次调试()调用时,我正在打印收到的
字节数
,该字节数为0。但是您没有正确生成
消息