- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我可能对此处的绑定(bind)一词有根本的误解,但我对 MulticastSocket 的用法感到困惑。它是构造函数。他们不会做我理解他们应该做的事情,因此任何能帮助我消除误解的人都将不胜感激。
首先是我想要达到的目标。我试图编写一个简短的程序来创建一个 MulticastSocket 将它绑定(bind)(即监听)在 上。特定网络适配器 然后加入特定的多播组。我已经尝试了以下(客户端)代码,它可以正常工作,我可以在没有多播套接字超时的情况下向它多播一个数据包。
public class Main {
public static final int DEFAULT_MULTICAST_PORT = 5555;
public static final String multicastGroup = "225.4.5.6";
public static final String adapterName = "eth0";
public static final int MAX_PACKET_SIZE = 65507;
CharBuffer charBuffer = null;
Charset charset = Charset.defaultCharset();
CharsetDecoder decoder = charset.newDecoder();
static ByteBuffer message = ByteBuffer.allocateDirect(MAX_PACKET_SIZE);
static boolean loop = true;
static byte[] buffer = new byte[MAX_PACKET_SIZE];
public static void main(String[] args) {
try {
//MulticastSocket mSocket = new MulticastSocket(new InetSocketAddress("192.168.2.23", DEFAULT_MULTICAST_PORT));
MulticastSocket mSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT);
mSocket.setReuseAddress(true);
mSocket.setSoTimeout(5000);
NetworkInterface nic = NetworkInterface.getByName(adapterName);
mSocket.joinGroup(new InetSocketAddress(multicastGroup, DEFAULT_MULTICAST_PORT),NetworkInterface.getByName(adapterName));
DatagramPacket p = new DatagramPacket(buffer, MAX_PACKET_SIZE);
while (loop){
try{
mSocket.receive(p);
System.out.println("Packet Received.");
} catch (SocketTimeoutException ex){
System.out.println("Socket Timed out");
}
}
} catch (IOException ex){
System.err.println(ex);
}
}
MulticastSocket(SocketAddress bindaddr)
它停止工作。似乎我只能使用绑定(bind)到端口的构造函数让它工作,所以当这个构造函数被调用时它究竟绑定(bind)到什么,因为我在这个阶段没有指定网络适配器。 (我知道我稍后会加入具有特定 NetworkInterface 的组,但是我如何确定在构造函数调用期间它不会绑定(bind)到任何适配器?)
joinGroup()
的调用如何。 .
joinGroup()
不对套接字本身做任何事情,而是向底层网络系统发出 IGMP 请求,以确保路由器、操作系统本身等实际开始将指定的多播数据包路由到硬件上并通过网络堆栈,最终到达 Java MulticastSocket 本身。
To receive a multicast datagram, a process must join the multicast group and it must also bind a UDP socket to the prot number that will be used as destination port number for datagrams sent to the group. The two operations are distinct and both are required. Joining the group tells the host's IP layer and datalink layer to receive multicast datagrams sent to that group. Binding the port is how the application specifies to UDP that it wants to receive datagrams sent to that port. Some applications also bind the multicast address to the socket, in addition to the port. this prevents any other datagrams that might be received for that port to other unicast, broadcast or multicast addresses from being delivered to the socket.
/**
* This first creates an UNBOUND Multicast Socket and then binds to
* a port (but accepting the wildcard IP 0.0.0.0.
* The Following WORKS:
*/
/*MulticastSocket mSocket = new MulticastSocket(null);
mSocket.bind(new InetSocketAddress(DEFAULT_MULTICAST_PORT));
mSocket.setReuseAddress(true);
mSocket.setSoTimeout(5000);
NetworkInterface nic = NetworkInterface.getByName(adapterName);
mSocket.joinGroup(InetAddress.getByName(multicastGroup));
*/
/**
* The following creates a a network socket and binds in the constructor
* to a local adapter and port. Consequently it DOES not work because
* it only allows destination ips that match the bound address & port
* even though the desired group is joined.
*/
/*MulticastSocket mSocket = new MulticastSocket(new InetSocketAddress("192.168.2.23", DEFAULT_MULTICAST_PORT));
mSocket.setReuseAddress(true);
mSocket.setSoTimeout(5000);
NetworkInterface nic = NetworkInterface.getByName(adapterName);
mSocket.joinGroup(InetAddress.getByName(multicastGroup));*/
/**
* The following binds to the same multicast group this is 'joined' later
* and this works correctly. However if the join() is NOT called, no packets
* arrive at the socket, as expected.
*/
/*MulticastSocket mSocket = new MulticastSocket(new InetSocketAddress(multicastGroup, DEFAULT_MULTICAST_PORT));
mSocket.setSoTimeout(5000);
NetworkInterface nic = NetworkInterface.getByName(adapterName);
// Comment out the following line and it no longer workds correctly.
mSocket.joinGroup(InetAddress.getByName(multicastGroup));*/
/**
* The following binds to a a specified port on 0.0.0.0 and joins
* a specific Multicast group on a specific adapter. This must mean that the IGMP must occur
* on the specified adapter.
*
* ** This will ALSO receive packets addressed DIRECTLY to the ip 192.168.2.23 with the same
* port as DEFAULT_MULTICAST_POR ***ONLY!!***
*/
MulticastSocket mSocket = new MulticastSocket(DEFAULT_MULTICAST_PORT);
mSocket.setReuseAddress(true);
mSocket.setSoTimeout(5000);
NetworkInterface nic = NetworkInterface.getByInetAddress(InetAddress.getByName("192.168.2.23"));
mSocket.joinGroup(new InetSocketAddress(multicastGroup, DEFAULT_MULTICAST_PORT),NetworkInterface.getByName(adapterName));
/**
* The following binds to a specific address and port (i.e. adapter address)
* and then ONLY accepts UDP packets with destination equal to that IP.
*/
/*MulticastSocket mSocket = new MulticastSocket(new InetSocketAddress("192.168.2.23", DEFAULT_MULTICAST_PORT));
mSocket.setReuseAddress(true);
mSocket.setSoTimeout(5000);
NetworkInterface nic = NetworkInterface.getByInetAddress(InetAddress.getByName("192.168.2.23"));*/
最佳答案
如果在创建或绑定(bind)时没有指定本地 IP 地址,它会绑定(bind)到 0.0.0.0,这意味着“通过任何 NIC 接受输入”。这通常是您想要的。
可以绑定(bind)到特定的 IP 地址,这隐式表示相应的 NIC,但是某些系统(例如 Linux)似乎希望多播套接字(如果绑定(bind))绑定(bind)到多播组本身。这对我来说没有任何意义:如果你想加入另一个小组怎么办?
我认为最好和最便携的想法是在 0.0.0.0 收听并通过特定的 NIC 或所有 NIC 加入,一次一个。后者在多宿主主机中是必需的,除非您确信到多播组的默认路由是您希望发送加入请求的路由,因为如果您不指定加入接口(interface),就会发生这种情况。
关于java - MulticastSocket 构造函数和绑定(bind)到端口或 SocketAddress,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19392173/
根据 DatagramChannel 的 Javadoc,接收方法: public abstract SocketAddress receive(ByteBuffer dst)
我有一个关于 Android 的问题。我正在尝试使用代理连接到服务器,但没有成功。 我的这段代码在普通 Java 上运行良好。它只定义一个代理服务器并创建一个套接字,该套接字将使用该代理连接到谷歌。它
我可能对此处的绑定(bind)一词有根本的误解,但我对 MulticastSocket 的用法感到困惑。它是构造函数。他们不会做我理解他们应该做的事情,因此任何能帮助我消除误解的人都将不胜感激。 首先
我只是好奇。那是一个API错误吗?当您加入多播组时,您不使用端口,只使用多播组的多播地址 (IP),对吧? 当使用 PORT 时,是否会出现这种情况? 最佳答案 这个问题最好改写为“为什么 Datag
我正在尝试以字符串形式获取套接字连接的 IP。 我正在使用一个框架,它返回接收到的消息的 SocketAddress。我如何将其转换为 InetSocketAddress 或 InetAddress?
为什么Socket.connect使用SocketAddress而不是InetSocketAddress? 我阅读了Socket.connect的源代码,它只是将SocketAddress转换为Ine
java.net.InetSocketAddress 和 java.net.SocketAddress 是否支持 IPv6? 因为我研究和尝试的两个类无法让我查看 ipv6 连接,所以它只能查看 ip
我是一名优秀的程序员,十分优秀!