效果图:
一,学习UDP的简单使用步骤
接收端:
DatagramSocket socket = null;
try {
//1.开启自己的端口(客户端连接的端口)
socket = new DatagramSocket(9999);
//2.接收数据
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);//堵塞接收
//3.处理数据
byte[] target = packet.getData();
int len=0;
if (target.length!=0){
for (int i=0;i<target.length;i++){
if (target[i]=='\0'){
len=i;
break;
}
}
}
//4.输出数据
System.out.println("from:"+packet.getAddress());
System.out.println(new String(target,0,len));
} catch (Exception e) {
e.printStackTrace();
}finally {
if (socket!=null){
socket.close();
}
}
发送端:
//1.建立连接
DatagramSocket socket = null;
//2.获得连接对象
//获取对方的IP和端口号进行连接
InetAddress Ip = null;
int port = 9999;
//4.创建数据包
String msg = "你好";
DatagramPacket packet = null;
try {
socket = new DatagramSocket();
Ip = InetAddress.getByName("localhost");
//数据,数据的长度起始,发送的地址
packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,Ip,port);
//5.发送包
socket.send(packet);
} catch (Exception e) {
e.printStackTrace();
}finally {
//6.关闭资源
if (socket != null){
socket.close();
}
}
二,多线程实现UDP在线聊天
1.创键服务器端
package chat;
import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
public class ServerThread implements Runnable{
private final String theOther;//对方的姓名
private final int selfPort;//自己开放的的端口号
private DatagramSocket socket;
public ServerThread(int selfPort,String theOther){//构造器
this.selfPort = selfPort;
this.theOther = theOther;
try {
//开启服务器
socket = new DatagramSocket(selfPort);
} catch (SocketException e) {
e.printStackTrace();
}
}
public void run() {
//接收数据
byte[] container;
DatagramPacket packet;//包
byte[] date;
String receiveMsg = "";//信号灯
int len = 0;
try {
while (!receiveMsg.equals("bye")){//如果对方说:bye,则退出聊天
container = new byte[1024];
packet = new DatagramPacket(container,0,container.length);
socket.receive(packet);//接收数据包
date =packet.getData();//获取数据
//处理数据
for (int i = 0; i < date.length; i++) {
if (date[i]=='\0'){
len = i;
break;
}
}
//将收到的数据转换为字符串
receiveMsg = new String(date,0, len, StandardCharsets.UTF_8);
System.out.println(theOther+":"+receiveMsg);
}
// 保存聊天记录(扩展内容)
// FileOutputStream out = new FileOutputStream(new File(theOther+"的聊天记录.txt"));
// out.write(receiveMsg.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭服务器
if (socket != null){
socket.close();
}
}
}
}
2.建立客户端
package chat;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.nio.charset.StandardCharsets;
public class ClientThread implements Runnable{
private DatagramSocket socket = null;
private BufferedReader bufferedReader= null;//缓冲流
private final String toIp;//对方的IP
private final int toPort;//对方的端口号
public ClientThread(String toIp, int toPort) {
this.toIp = toIp;
this.toPort = toPort;
try {
socket = new DatagramSocket();
bufferedReader = new BufferedReader(new InputStreamReader(System.in));//获取键盘输入
} catch (SocketException e) {
e.printStackTrace();
}
}
public void run() {
String SendMsg = "";//发视频美好的消息
byte[] date;
DatagramPacket packet;
try {
while(!SendMsg.equals("bye")) {//自己发送‘bye’时关闭发送端
SendMsg = bufferedReader.readLine();//读取键盘输入内容
date = SendMsg.getBytes(StandardCharsets.UTF_8);//字符串转换为字节进行传输
packet = new DatagramPacket(date,0,date.length,new InetSocketAddress(toIp,toPort));
socket.send(packet);//发送数据
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭数据流
if (bufferedReader!=null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
socket.close();
}
}
}
}
3.用户使用:
用户1:
package chat;
public class User01 {
public static void main(String[] args) {
System.out.println("小明的聊天室!!!");
new Thread(new ServerThread(9000,"小红")).start();//开启接收
new Thread(new ClientThread("localhost",9001)).start();//开启发送
}
}
用户2:
package chat;
public class User02 {
public static void main(String[] args) {
System.out.println("小红的聊天室!!!");
new Thread(new ServerThread(9001,"小明")).start();
new Thread(new ClientThread("localhost",9000)).start();
}
}
多人聊天思路:
用户—>公共服务器接收端打包数据–>服务器发送端发送给各个用户—>用户