网络编程
6 UDP
6.2.2 UDP聊天实现
“循环实现消息的发送和接收”
接收端只能接收到消息而无法反馈交流
接收:
package com.duo.chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UdpReceiveDemo1 {
public static void main(String[] args) throws Exception {
DatagramSocket datagramSocket = new DatagramSocket(6666);
while (true) {
//准备包裹:用于接收数据
byte[] container = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(container, 0,
container.length);
datagramSocket.receive(datagramPacket); //阻塞式接收包裹
//断开连接
byte[] bytes = datagramPacket.getData();
String data = new String(bytes, 0, bytes.length);
System.out.println(data);
if (data.equals("bye")) {
break;
}
}
datagramSocket.close();
}
}
发送:
package com.duo.chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class UdpSendDemo1 {
public static void main(String[] args) throws Exception {
DatagramSocket datagramSocket = new DatagramSocket(8888);
//准备数据:控制台读取 System.in
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String data = bufferedReader.readLine();
byte[] bytes = data.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0,
bytes.length, new InetSocketAddress("localhost", 6666));
datagramSocket.send(datagramPacket);
if (data.equals("bye")) {
break;
}
}
datagramSocket.close();
}
}
运行结果:
如上所示,可以在控制台中多次输入消息发送,接收方成功收到消息。在输入“bye”时,连接断开。
6.2.3 多线程在线咨询
将上述消息发送端和接收端代码实现多线程在线咨询
互相沟通交流(即双方都可以是发送方,也可以是接收方)
发送端:
package com.duo.chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
public class Send implements Runnable {
DatagramSocket datagramSocket = null;
BufferedReader bufferedReader = null;
private int fromPort;
private String toIP;
private int toPort;
public Send(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
try {
datagramSocket = new DatagramSocket(fromPort);
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
@Override
public void run() {
while (true) {
try {
String data = bufferedReader.readLine();
byte[] bytes = data.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0,
bytes.length, new InetSocketAddress(this.toIP, this.toPort));
datagramSocket.send(datagramPacket);
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
datagramSocket.close();
}
}
接收端:
package com.duo.chat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Receive implements Runnable {
DatagramSocket datagramSocket = null;
private int port;
private String msgFrom;
public Receive(int port, String msgFrom) {
this.port = port;
this.msgFrom = msgFrom;
try {
datagramSocket = new DatagramSocket(port);
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
@Override
public void run() {
while (true) {
try {
//准备包裹:用于接收数据
byte[] container = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(container, 0,
container.length);
datagramSocket.receive(datagramPacket); //阻塞式接收包裹
//断开连接
byte[] bytes = datagramPacket.getData();
String data = new String(bytes, 0, bytes.length);
System.out.println(msgFrom + ": " + data);
if (data.equals("bye")) {
break;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
datagramSocket.close();
}
}
然后写两个模拟在线咨询的对象:
老师:
package com.duo.chat;
public class Teacher {
public static void main(String[] args) {
new Thread(new Send(3333, "localhost", 4444)).start();
new Thread(new Receive(2222, "学生")).start();
}
}
学生:
package com.duo.chat;
public class Stundent {
public static void main(String[] args) {
new Thread(new Send(1111, "localhost", 2222)).start();
new Thread(new Receive(4444, "老师")).start();
}
}
运行结果: