在学习了UDP编程后,就想写一个程序,向qq一样,甲可以在控制台上输入信息,信息将被通过udp发送给乙,控制台上显示自己的消息和对方的消息。
但是我尝试了很多方式,都有问题。不能消息接收与控制台输入同时进行。控制台输入时就不能接受消息,接受消息时不能输入。最后我尝试了使用多线程,一个线程负责接受消息,并将接受的消息打印在控制台上,另一个线程负责监控控制台输入,一旦控制台有输入,就将消息打印在控制台上,并将输入发送给另一方。
一、这是一个工具类负责发送、接受消息。第22行,记得更改计算机名。
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Tool {
private DatagramSocket socket;
private int port;
public Tool(DatagramSocket socket, int port) {
this.socket = socket;
this.port = port;
}
/**
* 发送消息
* @param message 消息
*/
public void send(String message) {
try {
byte[] bytes = message.getBytes();
InetAddress address = InetAddress.getByName("你的主机名");
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 接受消息
* @return 消息
*/
public String receive() {
byte[] by = new byte[1024];
DatagramPacket p = new DatagramPacket(by, by.length);
try {
socket.receive(p);
} catch (IOException e) {
e.printStackTrace();
}
return new String(p.getData(), 0, p.getLength());
}
}
二、这是线程类,负责执行发送消息
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramSocket;
import java.util.ArrayList;
import java.util.List;
public class Send implements Runnable {
private Tool tool;
public Send(DatagramSocket socket, int port) {
tool = new Tool(socket, port);
}
@Override
public void run() {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String s = br.readLine();
while (s != null) {
synchronized (this) {
if (!s.equals("")) {
System.out.println("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t本人:" + s);
tool.send(s);
}
}
s = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、这是线程类,负责执行接受消息
import java.net.DatagramSocket;
import java.util.ArrayList;
import java.util.List;
public class Receive implements Runnable {
public static final List<String> messages = new ArrayList<>();
private Tool tool;
public Receive(DatagramSocket socket, int port) {
tool = new Tool(socket, port);
}
@Override
public void run() {
while (true) {
synchronized (this) {
String s = tool.receive();
System.out.println("\t\t\t\t\t\t朋友:" + s);
}
}
}
}
四、下面两个类代表两个聊天用户,分别调用线程类。
import java.io.IOException;
import java.net.DatagramSocket;
public class User1 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(10086);
Send send = new Send(socket, 10010);
Receive receive = new Receive(socket, 10010);
Thread t1 = new Thread(send);
Thread t2 = new Thread(receive);
t1.start();
t2.start();
}
}
import java.io.IOException;
import java.net.DatagramSocket;
public class User2 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(10010);
Send send = new Send(socket, 10086);
Receive receive = new Receive(socket, 10086);
Thread t1 = new Thread(send);
Thread t2 = new Thread(receive);
t1.start();
t2.start();
}
}
效果如下: