任務描述
本文主要講如何實現(xiàn)Java控制臺和網(wǎng)絡調(diào)試工具(以下簡稱"工具")實現(xiàn)"聊天".
也就是說, Java控制臺輸入消息, 按回車鍵盤, 工具上顯示消息, 然后工具上發(fā)送消息, 控制臺打印消息.
注意的是, 這里實現(xiàn)思路存在弊端: 即Java一次只能發(fā)送一條消息給工具, 因為Java的發(fā)送端以一個線程來運作的, 而這個線程由接收端線程喚醒. 這么做的原因是因為要兩個線程要共用一個Java控制臺, 避免流沖突.
什么是網(wǎng)絡調(diào)試工具
上圖. 看起來和QQ聊天窗口一樣樣的.

Paste_Image.png
實現(xiàn)流程圖
總的來說, 利用兩個線程: 發(fā)送端線程和接收端線程分別完成發(fā)送和接收的任務.

Java利用UDP模式模擬聊天.png
代碼
- main方法代碼片
public class demo78 {
// 2017年9月15日 上午12:19:14 Nisus
public static void main(String[] args) throws IOException, InterruptedException {
DatagramSocket socket = new DatagramSocket(6567); //固定住端口號, 兩個線程共用. 注意: 工具上發(fā)送消息是根據(jù)獲取的發(fā)送端端口號發(fā)送的, 如果接收端不監(jiān)聽一致的端口號, 將不能接受工具發(fā)來的消息.
new Thread(new ReceiveMsg(socket)).start(); //開啟接收端線程
Thread.sleep(100); //保證接受端線程先開啟
new Thread(new SendMsg(socket)).start(); //開啟發(fā)送端線程
}
- 接收端線程
/*
* 接收消息進程
*/
static class ReceiveMsg implements Runnable {
private DatagramSocket socket;
public ReceiveMsg(DatagramSocket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
// 2017年9月15日 上午1:08:54 Nisus
byte[] buf = new byte[1024];
DatagramPacket pkt = new DatagramPacket(buf, buf.length);
while(true) {
try {
socket.receive(pkt); //等待監(jiān)聽
int datalen = pkt.getLength();
InetAddress address = pkt.getAddress();
byte[] b = pkt.getData();
System.out.println(address + ": " + new String(b,0,datalen));
}catch(Exception e) {
}
//到這里說明發(fā)送端發(fā)送數(shù)據(jù)了, 且wait()了
synchronized ("") {
"".notify();
}
}
}
}
- 發(fā)送端線程
/*
* 發(fā)送消息進程
*/
static class SendMsg implements Runnable{
private DatagramSocket socket;
public SendMsg(DatagramSocket socket) {
super();
this.socket = socket;
}
@Override
public void run() {
// 2017年9月15日 上午12:59:53 Nisus
Scanner sc = new Scanner(System.in);
while(true) {
synchronized ("") {
try {
String sender = sc.nextLine();
byte[] buf = sender.getBytes("gbk");
DatagramPacket pkt = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.117.22"), 8888); //綁定工具IP和端口號, 這里IP就是本機IP, 端口號在工具上手動設置成了8888
socket.send(pkt);
"".wait(); //發(fā)送完后等待
// Thread.sleep(5000);
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
}
效果圖

Paste_Image.png