一、前提
在做一个pc服务器(eclipse)向android客户端发送udp广播的功能(同一电脑上测试),android始终收不到数据
电脑ip:192.168.0.19
真机手机ip:192.168.0.24
android模拟器ip:10.0.2.15
pc服务器私网地址:10.0.2.2
子网掩码:255.255.255.0
二、问题
真机上可以收到,广播地址为192.168.0.255(端口号相同即可),模拟器上收不到(试了很多地址都不行)
原因:
端口、广播地址不对,两边设置了同一端口(22222),这时电脑的22222端口并没有开启,开启的是模拟器的22222端口,需要进行模拟器与pc端口映射
解决:
a.命令行中输入 telnet 127.0.0.1 5554 进入虚拟机,5554为虚拟机的端口号,若提示telnet不是内部或外部命令,百度解决Win7如何解决telnet不是内部或外部命令的方案
b.上一步完成后出现C:\Users\Administrator.emulator_console_auth_token,找到此文件并打开复制里面字符串,在telnet命令行中输入:auth XXXXX(刚复制的字符串),
(auth 若出问题,好像是要加上adb环境变量,即把sdk下的tools和platfrom-tools加到系统环境变量path中)
c.端口映射:redir add udp:22222:22222(redir add < udp/tcp >: < pc端口 >: < 模拟器端口 >),第二步不成功会提示KO: unknown command, try 'help'
d.redir list 可以查看已映射列表
e.使用完删除映射:redir del udp:22222
结果:
android设置22222端口接收,发送端设置127.0.0.1 22222发送
疑问:
广播地址设置255.255.255.255、192.168.0.255、10.0.2.255...都不行,只有127.0.0.1可以,why?
(后来测试时,192.168.0.255可以)
三、广播域计算
用主机的IP地址与子网掩码进行与运算即可知道该主机属于哪一个广播域。例如:一台主机的IP地址为192.168.23.150,子网掩码为255.255.255.0,那么它所属的广播域就是192.168.23.150&255.255.255.0=192.168.23.0。那么其它的在广播域192.168.23.0内的所有主机就可以到该设备发送的广播包。如果把子网掩码改为255.255.0.0,那么它所属的广播域就是192.168.23.150&255.255.0.0=192.168.0.0。那么其它的在广播域192.168.0.0内的所有主机都可以收到该设备发送的广播包。
四、广播地址的计算
要想相同广播域内的其它主机能收到的广播帧,还需要在发送广播包的时候指定当前所属广播域内的广播地址。广播地址的计算方法为子网掩码取反再与广播域进行或运算。
例如:如果主机当前所属广播域为192.168.0.0,子网掩码为255.255.0.0,那么广播地址则为192.168.255.255。
五、udp跨网段广播
要使主机A发送的广播包能够被另一网段的主机B收到,那么只需要更改主机A的子网掩码使得与主机B在同一个广播域内,再使用新的广播域的广播地址发送广播包即可。
例如:要使用192.168.23.150发送广播包让192.168.27.135收到,只需要设置192.168.23.150的子网掩码为255.255.0.0,然后再使用广播地址192.168.255.255即可。
广播UDP与单播UDP的区别就是IP地址不同,广播使用广播地址255.255.255.255,将消息发送到在同一广播网络上的每个主机。值得强调的是:本地广播信息是不会被路由器转发。当然这是十分容易理解的,因为如果路由器转发了广播信息,那么势必会引起网络瘫痪。这也是为什么IP协议的设计者故意没有定义互联网范围的广播机制。特别要指出的是:255.255.255.255是受限广播地址
其实广播顾名思义,就是想局域网内所有的人说话,但是广播还是要指明接收者的端口号的,因为不可能接受者的所有端口都来收听广播。