任务描述
本文主要讲如何实现Java控制台和网络调试工具
(以下简称"工具")实现"聊天".
也就是说, Java控制台输入消息, 按回车键盘, 工具上显示消息, 然后工具上发送消息, 控制台打印消息.
注意的是, 这里实现思路存在弊端: 即Java一次只能发送一条消息给工具, 因为Java的发送端以一个线程来运作的, 而这个线程由接收端线程唤醒. 这么做的原因是因为要两个线程要共用一个Java控制台, 避免流冲突.
什么是网络调试工具
上图. 看起来和QQ聊天窗口一样样的.
实现流程图
总的来说, 利用两个线程: 发送端线程和接收端线程分别完成发送和接收的任务.
代码
- 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); //固定住端口号, 两个线程共用. 注意: 工具上发送消息是根据获取的发送端端口号发送的, 如果接收端不监听一致的端口号, 将不能接受工具发来的消息.
new Thread(new ReceiveMsg(socket)).start(); //开启接收端线程
Thread.sleep(100); //保证接受端线程先开启
new Thread(new SendMsg(socket)).start(); //开启发送端线程
}
- 接收端线程
/*
* 接收消息进程
*/
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); //等待监听
int datalen = pkt.getLength();
InetAddress address = pkt.getAddress();
byte[] b = pkt.getData();
System.out.println(address + ": " + new String(b,0,datalen));
}catch(Exception e) {
}
//到这里说明发送端发送数据了, 且wait()了
synchronized ("") {
"".notify();
}
}
}
}
- 发送端线程
/*
* 发送消息进程
*/
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(); //发送完后等待
// Thread.sleep(5000);
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
}