从esp8266中的多播消息中查找源地址?
Find source address from multicast message in esp8266?
我正在为 esp8266 使用非OS SDK v2.0。
我加入了多播组。
然后我收到一条消息(发送到多播)。
我想回复发件人,但是在struct espconn
中,udp.remote_ip
是多播组的地址,不是发件人
如何获取发件人的IP地址?
编辑:
接收函数有一个 void* arg
参数被转换为 struct espconn
.
旧方法不再适用,但我找到了一种查找远程 ip 和端口的方法。
新代码:
struct espconn* udp_ch;
remot_info *premot = NULL;
udp_ch = arg;
if (espconn_get_connection_info(udp_ch,&premot,0) == ESPCONN_OK){
os_printf("%d.%d.%d.%d:%d\n", premot->remote_ip[0], premot->remote_ip[1], premot->remote_ip[2], premot->remote_ip[3], premot->remote_port);
}
else{
os_printf("Get info fail\n");
}
这正是我之前搜索的内容。目前,据我所知,它运行良好。
旧:
我找到了一种查找ip的方法,但我认为不应该这样做。在我找到更好的之前,我会使用它。
我做的第一件事是打印前 256 个十六进制值,来自 void* arg
。
我注意到我的地址出现在一堆零之前。
在单播中,0s的起始位置是128。
我目前正在使用这个功能:
uint32_t udp_get_addr(void* arg){
uint32_t adr = 0;
uint16_t pos;
uint8_t* data = (uint8_t*) arg;
//unicast?
for(pos = 128; pos<144; pos++){
if(data[pos] != 0){
adr = 1;
break;
}
}
//multicast
if(adr == 1)
pos = 172;
else
pos = 124;
adr = data[pos]<<24 | data[pos+1]<<16 | data[pos+2]<<8 | data[pos+3];
return adr;
}
我知道这个方法不好,还有很多地方可以改进,但现在,这个就可以了。
编辑2:
我也需要源端口。它位于地址前 4 个字节。我目前使用的新功能:
#define SRC_ADDR_U 120
#define SRC_ADDR_M 168
uint32_t udp_src_addr(void* arg, uint8_t isMulticast){
uint32_t res;
uint8_t* tmp = (uint8_t*) arg;
uint16_t pos;
if(isMulticast) pos = SRC_ADDR_M+4;
else pos = SRC_ADDR_U+4;
res = (tmp[pos+3] << 24) | (tmp[pos+2] << 16) | (tmp[pos+1] << 8) | tmp[pos];
return res;
}
uint16_t udp_src_port(void* arg, uint8_t isMulticast){
uint32_t res;
uint8_t* tmp = (uint8_t*) arg;
uint16_t pos;
if(isMulticast) pos = SRC_ADDR_M;
else pos = SRC_ADDR_U;
res = (tmp[pos+1] << 8) | tmp[pos];
return res;
}
我正在为 esp8266 使用非OS SDK v2.0。
我加入了多播组。
然后我收到一条消息(发送到多播)。
我想回复发件人,但是在struct espconn
中,udp.remote_ip
是多播组的地址,不是发件人
如何获取发件人的IP地址?
编辑:
接收函数有一个 void* arg
参数被转换为 struct espconn
.
旧方法不再适用,但我找到了一种查找远程 ip 和端口的方法。
新代码:
struct espconn* udp_ch;
remot_info *premot = NULL;
udp_ch = arg;
if (espconn_get_connection_info(udp_ch,&premot,0) == ESPCONN_OK){
os_printf("%d.%d.%d.%d:%d\n", premot->remote_ip[0], premot->remote_ip[1], premot->remote_ip[2], premot->remote_ip[3], premot->remote_port);
}
else{
os_printf("Get info fail\n");
}
这正是我之前搜索的内容。目前,据我所知,它运行良好。
旧:
我找到了一种查找ip的方法,但我认为不应该这样做。在我找到更好的之前,我会使用它。
我做的第一件事是打印前 256 个十六进制值,来自 void* arg
。
我注意到我的地址出现在一堆零之前。
在单播中,0s的起始位置是128。
我目前正在使用这个功能:
uint32_t udp_get_addr(void* arg){
uint32_t adr = 0;
uint16_t pos;
uint8_t* data = (uint8_t*) arg;
//unicast?
for(pos = 128; pos<144; pos++){
if(data[pos] != 0){
adr = 1;
break;
}
}
//multicast
if(adr == 1)
pos = 172;
else
pos = 124;
adr = data[pos]<<24 | data[pos+1]<<16 | data[pos+2]<<8 | data[pos+3];
return adr;
}
我知道这个方法不好,还有很多地方可以改进,但现在,这个就可以了。
编辑2:
我也需要源端口。它位于地址前 4 个字节。我目前使用的新功能:
#define SRC_ADDR_U 120
#define SRC_ADDR_M 168
uint32_t udp_src_addr(void* arg, uint8_t isMulticast){
uint32_t res;
uint8_t* tmp = (uint8_t*) arg;
uint16_t pos;
if(isMulticast) pos = SRC_ADDR_M+4;
else pos = SRC_ADDR_U+4;
res = (tmp[pos+3] << 24) | (tmp[pos+2] << 16) | (tmp[pos+1] << 8) | tmp[pos];
return res;
}
uint16_t udp_src_port(void* arg, uint8_t isMulticast){
uint32_t res;
uint8_t* tmp = (uint8_t*) arg;
uint16_t pos;
if(isMulticast) pos = SRC_ADDR_M;
else pos = SRC_ADDR_U;
res = (tmp[pos+1] << 8) | tmp[pos];
return res;
}