package udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
// Server 必须公开出 port,否则客户端找不到我
// 端口(port) 可以在 0 - 65535 之间随便选
// 但是不能使用已经被其他进程使用的端口 —— 端口只能属于唯一的一个进程
public class Server {
static final int PORT = 9527;
static final String CHARSET = "UTF-8";
public static void main(String[] args) throws IOException {
// 创建套接字
// DatagramSocket 是 UDP 协议专用的 套接字
// PORT 是我选好的准备开饭店的地址
try (DatagramSocket serverSocket = new DatagramSocket(PORT)) {
System.out.printf(" 和用户 %d 聊天中.... %n", PORT);
// 提前准备好一个字节数组,用来存放接收到的数据(请求)
// 一次最多可以接收 8192 个字节
byte[] receiveBuffer = new byte[8192];
while (true) {
// 一次循环就是 一次 请求-响应 的处理过程
// 1. 接收对方发送来的请求(数据)
// 1.1 必须先创建 DatagramPacket 数据报文对象
DatagramPacket packetFromClient = new DatagramPacket(
receiveBuffer, 0, receiveBuffer.length
);
// 1.2 接收数据
serverSocket.receive(packetFromClient); // 这个方法不是立即返回的,和 scanner.nextLine();
// 当走到这里时,数据一定接收到了
// packetFromClient.getLength(); 一个收到了多少字节的数据
// 1.3 因为我们收到的是字节格式的数据,所以我们把数据节码成字符格式的
// 需要字符集编码的知识
// 利用 String 的一个构造方法,把字节数组的数据解码(decode)成字符格式的数据 String
String request = new String(
receiveBuffer, 0, packetFromClient.getLength(),
CHARSET
);
System.out.println("对方: " + request);
InetAddress hisIP = packetFromClient.getAddress(); //获取对面的IP
int hisPort = packetFromClient.getPort();//获取对面的端口ID
byte[] back =request.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(
back,0,back.length,
hisIP,hisPort
);
serverSocket.send(datagramPacket);
}
}
}
}
//=====================以上为服务器
package udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class Client {
// 这里使用 127.0.0.1 代表本机
private static final String serverIP = "127.0.0.1";
public static void main(String[] args) throws IOException {
// 创建 UDP Socket 的
// 不需要传入端口,让 OS 自动分配一个
try (DatagramSocket clientSocket = new DatagramSocket()) {
System.out.println("请输入内容-->>");
while (true) {
// 1. 准备好请求,同时,传输的必须是字符格式
Scanner scan = new Scanner(System.in);
String request = scan.nextLine();
byte[] requestBytes = request.getBytes(Server.CHARSET);
// 2. 发送请求
// 2.1 先准备 DatagramPacket
// 需要指定服务器的 ip + port
DatagramPacket packetToServer = new DatagramPacket(
requestBytes, 0, requestBytes.length, // 要发送的数据
InetAddress.getByName(serverIP), Server.PORT // 要发送到互联网的哪个进程上
);
clientSocket.send(packetToServer);
byte[] 回执 = new byte[8912];
DatagramPacket 接收 = new DatagramPacket(
回执,0,回执.length
);
clientSocket.receive(接收);
String 内容 = new String(回执,0,接收.getLength(),Server.CHARSET);
System.out.println("你:" + 内容);
}
}
}
}
服务端:
创建自己的端口ID,并且用数据报文对象来接收传入的文本,
然后用数据报文对象来获取对方的ID,IP,再做一个数据报文对象,用套接字的方法吧他发射回对方,让对方的设备上有自己的聊天记录。
用户端:
将以上发收操作反过来。