前面我写过一篇文章讲java实现组播,今天我们就来看看java怎么实现局域网内单播。
我们先来补充一下网络编程的两个要点:
1. 以进程为对象来看待问题会比较简单一点。进程是最小的程序单元,而网络进程在建立网络连接的时候会占用一个端口。
2. 我们所说的单播和组播,其实都是进程间通信。
所以实现单播最重要的是指定IP地址和进程端口。
如果是本机测试,IP地址相同是必然的,只要发送进程和接收进程使用不同的端口(注意在发送时保持目的端口与接收进程的端口一致)就可以互相通信,否则会出现IP地址被占用的异常。
局域网内单播有两种实现方式:一种是无连接方式,另一种是面向连接方式。
我们先来看无连接的方式:
首先我们继承DatagramSocket类,并封装了发送和接收消息的方法。
import java.net.*; import java.io.*; /** * 继承数据报套接字类 * 实现发送消息和接收消息的方法 * @author michael * */ public class MyDatagramSocket extends DatagramSocket { static final int MAX_LEN = 100; MyDatagramSocket() throws SocketException { super(); } MyDatagramSocket(int port) throws SocketException { super(port); } public void sendMessage(InetAddress receiverHost, int receiverPort, String message) throws IOException { byte[] sendBuffer = message.getBytes(); DatagramPacket datagram = new DatagramPacket(sendBuffer, sendBuffer.length, receiverHost, receiverPort); this.send(datagram); } public String receiveMessage() throws IOException { byte[] receiveBuffer = new byte[MAX_LEN]; DatagramPacket datagram = new DatagramPacket(receiveBuffer, MAX_LEN); this.receive(datagram); String message = new String(receiveBuffer); return message; } }
接下来我们看接收方:
import java.net.*; /** * 采用无连接的方式实现进程间通信 * @author michael * */ public class Receiver { public static void main(String[] args) { try { InetAddress receiverHost = InetAddress.getByName("127.0.0.1"); int myPort = 1234;// 本进程端口 int receiverPort = 5689;// 接收进程的端口 String message = "Hi Sender"; MyDatagramSocket mySocket = new MyDatagramSocket(myPort); System.out.println(mySocket.receiveMessage()); mySocket.sendMessage(receiverHost, receiverPort, message); mySocket.close(); } catch (Exception ex) { System.out.println(ex); } } }
发送方:
import java.net.*; /** * 采用无连接的方式实现进程间通信 * @author michael * */ public class Sender { public static void main(String[] args) { try { InetAddress receiverHost = InetAddress.getByName("127.0.0.1"); int myPort = 5689; int receiverPort = 1234; String message = "Hello Receiver"; MyDatagramSocket mySocket = new MyDatagramSocket(myPort); mySocket.sendMessage(receiverHost, receiverPort, message); System.out.println(mySocket.receiveMessage()); mySocket.close(); } catch (Exception ex) { } } }
代码里面我采用的是本机测试,不过我试过了联机测试,是可以的。
下面再看面向连接的方式:
面向连接的方式跟无连接的方式大体相同,只是多了一个建立连接和断开连接的过程。
import java.net.*; /** * 采用面向连接的方式实现进程间通信 * @author michael * */ public class Receiver { public static void main(String[] args) { try { InetAddress senderHost = InetAddress.getByName("127.0.0.1"); int senderPort = 1234; int myPort = 4568; String message = "Hi Sender"; MyDatagramSocket mySocket = new MyDatagramSocket(myPort); //与对方建立连接 mySocket.connect(senderHost, senderPort); System.out.println(mySocket.receiveMessage()); mySocket.sendMessage(senderHost, senderPort, message); //断开连接 mySocket.disconnect(); mySocket.close(); } catch (Exception ex) { System.out.println("An exception has occured: " + ex); } } }
import java.net.*; /** * 采用面向连接的方式实现进程间通信 * @author michael * */ public class Sender { public static void main(String[] args) { try { InetAddress receiverHost = InetAddress.getByName("127.0.0.1"); int receiverPort = 4568; int myPort = 1234; String message = "Hello Receiver"; MyDatagramSocket mySocket = new MyDatagramSocket(myPort); mySocket.connect(receiverHost, receiverPort); mySocket.sendMessage(receiverHost, receiverPort, message); System.out.println(mySocket.receiveMessage()); mySocket.disconnect(); mySocket.close(); } catch (Exception ex) { System.out.println(ex); } } }测试跟前面一样。