Java网络编程:使用DatagramSocket实现简单聊天功能
使用DatagramSocke和DatagramPacket实现简单的聊天室功能,具体如下:
- 使用DatagramSocke打开端口用来接收和发送数据
- 使用DatagramPacket对数据进行打包
- 实现Runnable接口启动一个接收线程和一个发送线程
- 使用UDP协议进行通讯
UDP协议通讯类似于发短信功能,无需握手连接,实现较为简单。
发送线程
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
public class UdpSend implements Runnable{
DatagramSocket socket = null;
BufferedReader reader = null;
private int fromPort;
private String toIP;
private int toPort;
public UdpSend(int fromPort, String toIP, int toPort) throws Exception {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
socket = new DatagramSocket(fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
}
@Override
public void run() {
while(true) {
try {
//读取控制台数据
String data = reader.readLine();
byte[] datas = data.getBytes();
//创建包
DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));
//发送包
socket.send(packet);
if(data.equals("bye")){//取消发送条件
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}socket.close();
}
}
接收线程
public class UdpReceive implements Runnable {
DatagramSocket socket = null;
private int ownPort;
private String msgFrom;
public UdpReceive(int ownPort, String msgFrom) throws Exception {
this.ownPort = ownPort;
this.msgFrom = msgFrom;
socket = new DatagramSocket(ownPort);
}
@Override
public void run() {
while (true) {
try {
//接受数据包
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);//阻塞接收
byte[] data = packet.getData();
int len = packet.getLength();
String receiveData = new String(data, 0, len);
System.out.println(msgFrom+":"+receiveData);
if (receiveData.equals("bye")) {
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
socket.close();
}
}
学生端
public class student {
public static void main(String[] args) throws Exception {
new Thread(new UdpReceive(7777,"老师")).start();
new Thread(new UdpSend(8888,"localhost",9090)).start();
}
}
老师端
public class teacher {
public static void main(String[] args) throws Exception {
new Thread(new UdpReceive(9090,"学生")).start();
new Thread(new UdpSend(9999,"localhost",7777)).start();
}
}
遇到的Bug
在控制台显示数据包时,数据后面会跟许多空格:

经查找原因,发现是由于收到数据包转换为String类型时数据长度设置错误:
//错误示范
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);//阻塞接收
byte[] data = packet.getData();//获取数据包中的数据
String receiveData = new String(data, 0, data.length);//此处数据长度不可使用数组的长度
System.out.println(msgFrom+":"+receiveData);
//正确代码
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);//阻塞接收
byte[] data = packet.getData();
int len = packet.getLength();//使用DatagramPacket的getLength()方法获取数据的长度。
String receiveData = new String(data, 0, len);//使用正确的长度参数即可避免错误。
System.out.println(msgFrom+":"+receiveData);
Seven times have I despised my soul:
The first time when I saw her being meek that she might attain height.
The second time when I saw her limping before the crippled.
The third time when she was given to choose between the hard and the easy, and she chose the easy.
The fourth time when she committed a wrong, and comforted herself that others also commit wrong.
The fifth time when she forbore for weakness, and attributed her patience to strength.
The sixth time when she despised the ugliness of a face, and knew not that it was one of her own masks.
And the seventh time when she sang a song of praise, and deemed it a virtue.

浙公网安备 33010602011771号