JAVA 网络编程(5) SOCKET UDP 单播和组播,以及组播其他机器收不到报文的解决方法

23 篇文章 1 订阅
16 篇文章 0 订阅

UDP既可以单播也可以组播

一,单播

单播的过程为

发送方:

InetAddress destAddr = InetAddress.getByName("192.168.4.199");// 发送的目的地址
int targetPort = 3001; // 发送的目的端口
DatagramSocket socket = new DatagramSocket();
byte[] b = “信息”.getBytes();
DatagramPacket pk = new DatagramPacket(b, b.length, destAddr, targetPort);
socket.send(pk);//发送

接收方:

int port = 3001;//接收数据包的IP端口
DatagramSocket socket = new DatagramSocket(port);
byte b[] = new byte[512];
DatagramPacket pack = new DatagramPacket(b, b.length);
socket.receive(pack);//接收信息
int length = pack.getLength();
String msg = new String(pack.getData(),0,length);
Logger.getGlobal().info(msg);

代码示例:

/**
 * 001 UDP单播发送,启动后在控制台输出
 */
public class SSend {

	public static void main(String[] args) throws SocketException, IOException {
		InetAddress destAddr = InetAddress.getByName("192.168.4.199");// 发送的目的地址
		int targetPort = 3001; // 发送的目的端口
		try (DatagramSocket socket = new DatagramSocket(); Scanner r = new Scanner(System.in);) {
			while (true) {
				String s = r.nextLine();
				byte[] b = s.getBytes();
				DatagramPacket pk = new DatagramPacket(b, b.length, destAddr, targetPort);
				socket.send(pk);//发送
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
/**
 * 001
 * UDP单播接收服务
 */
public class SReceive {

	public static void main(String[] args) throws UnknownHostException {
		int port = 3001;//接收数据包的IP端口
		try(
			DatagramSocket socket = new DatagramSocket(port);) {
			byte b[] = new byte[512];
			DatagramPacket pack = new DatagramPacket(b, b.length);
			while(socket!=null)
			{
				socket.receive(pack);//接收信息
				int length = pack.getLength();
				String msg = new String(pack.getData(),0,length);
				Logger.getGlobal().info(msg);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


二,组播

组播使用D类地址,D类地址不会被写入IP报文的源地址IP

我们使用D类地址中的用户组播地(224.0.2.0~238.255.255.255)址来测试

发送方:

MulticastSocket socket = new MulticastSocket(2011);
InetAddress mcastaddr = InetAddress.getByName("224.116.8.0");
socket.joinGroup(mcastaddr);//加入 组播组
byte[] b = msg.getBytes();
DatagramPacket pack = new DatagramPacket(b, b.length, mcastaddr, port);
socket.send(pack);//组播发送 数据报,可被group成员接收到

接收方和发送方开始的代码类似,都是指定IP和端口,加入组播组:

InetAddress mcastaddr = InetAddress.getByName("224.116.8.0");
MulticastSocket socket = new MulticastSocket(port);
socket.joinGroup(mcastaddr);
byte b[] = new byte[512];
DatagramPacket pack = new DatagramPacket(b, b.length, mcastaddr, port);
socket.receive(pack);
String msg = new String(pack.getData(), 0, b.length);
Logger.getGlobal().info(msg);

示例代码:

/**
 * 002组播 输出接收到的字符串
 */
public class MReceive {

	public static void main(String[] args) {
		String host = "224.116.8.0";
		int port = 2011;
		try (MulticastSocket socket = new MulticastSocket(port);) {
			InetAddress mcastaddr = InetAddress.getByName(host);
			socket.joinGroup(mcastaddr);
			byte b[] = new byte[512];
			DatagramPacket pack = new DatagramPacket(b, b.length, mcastaddr, port);
			while (true) {
				socket.receive(pack);
				String msg = new String(pack.getData(), 0, b.length);
				Logger.getGlobal().info(msg);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
<pre name="code" class="java">/**
 * 002 组播
 */
public class MSend {
	private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd-hh:mm:ss:SSS");// 显示日期格式

	public static void main(String[] args) {
		String host = "224.116.8.0";
		int port = 2011;
		Timer t = new Timer();
		t.schedule(new TimerTask() {
			@Override
			public void run() {
				send(host, port, SDF.format(new Date()));
			}
		}, 0, 2000);
	}

	public static void send(String addr, int port, String msg) {
		try (MulticastSocket socket = new MulticastSocket(port);) {
			// TTL从字面上翻译,是可以存活的时间,但实际上TTL是IP数据包在计算机网络中可以转发的最大跳数,1为本地网络
			socket.setTimeToLive(1);
			InetAddress mcastaddr = InetAddress.getByName(addr);
			socket.joinGroup(mcastaddr);// 加入 组播组
			byte[] b = msg.getBytes();
			DatagramPacket pack = new DatagramPacket(b, b.length, mcastaddr, port);
			// 待发送数据包
			socket.send(pack);// 组播发送 数据报,可被group成员接收到
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 
三,组播各个机器不互通的解决方法 

由于单播是指定发送目的的IP和端口,所有只要能ping通对方的IP就能将单播的UDP报文发送过去。

但是对于组播,由于加入和发送的目的是D类地址,所以得保证各个机器之间是同一个网段

①禁止其他网卡,只保留一块网卡(我是将笔记本的无线网卡金庸,只用我的有线网卡),以及公司的台式机

②修改IP和网关,确认在同一网段

下面是我的电脑我另一台测试电脑的网络设置




  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值