基于UDP的demo——实现用户端查询英文单词,客户端翻译回复用户
程序员文章站
2022-03-10 22:08:08
...
前言
这篇文章就是让你体验代码的乐趣的,所以首先要做的事情就是拷贝这两份代码运行起来。
UdpClient
import org.omg.IOP.Encoding;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class UdpClient {
// 定义发送数据报的目的地
public static final int DEST_PORT = 30000;
public static final String DEST_IP = "127.0.0.1";
// 定义每个数据报的最大大小为4K
private static final int DATA_LEN = 4096;
// 定义接收网络数据的字节数组
byte[] inBuff = new byte[DATA_LEN];
// 创建接受回复数据的DatagramPacket对象
private DatagramPacket packet_in = new DatagramPacket(inBuff, inBuff.length);
// 定义一个用于发送的DatagramPacket对象
private DatagramPacket packet_out = null;
public void start() throws IOException {
try (DatagramSocket socket = new DatagramSocket()) {
// 初始化发送用的DatagramSocket
InetAddress ip = InetAddress.getByName(DEST_IP);
packet_out = new DatagramPacket(new byte[0], 0, ip, DEST_PORT);
// 创建键盘输入流
Scanner sc = new Scanner(System.in);
System.out.println("请输入数据");
// 不断读取键盘输入
String key =null;
// 键盘输入字符对应的byte数组
byte[] keyBuff = null;
while (sc.hasNextLine()) {
key = sc.nextLine();
if ("exit".equals(key)) {
break;
}
// 输入的字符串→字节数组
//TODO
keyBuff= key.getBytes("UTF-8");
//keyBuff = key.getBytes();
// 设置发送用的DatagramPacket里的字节数据
packet_out.setData(keyBuff);
// 发送数据报
socket.send(packet_out);
// 读取Socket中的数据,读到的数据放在inPacket所封装的字节数组里。
socket.receive(packet_in);
System.out.println(new String(inBuff, 0, packet_in.getLength()));
System.out.println("请输入数据:");
}
System.out.println("=== 客户端退出 ===");
}
}
public static void main(String[] args) throws IOException {
new UdpClient().start();
}
}
UdpDictServer
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.Map;
public class UdpDictServer {
public static void main(String[] args) throws Exception {
new UdpDictServer().start();
}
// 定义udp端口号
public static final int PORT = 30000;
// 每个数据报最大为4K
private static final int DATA_LEN = 4096;
// 接收网络数据的字节数组
byte[] buff_in = new byte[DATA_LEN];
// 以指定字节数组创建准备接受数据的DatagramPacket对象
private DatagramPacket packet_in = new DatagramPacket(buff_in, buff_in.length);
// 定义一个用于发送的DatagramPacket对象
private DatagramPacket packet_out;
public void start() throws Exception {
try(DatagramSocket socket = new DatagramSocket(PORT)){
String key = null; // 客户端输入的英文单词
String value=null; // 服务端翻译的中文内容
SocketAddress address=null; // 获取客户端对象,通过该对象将数据写给对方,否则没有目的地
byte[] reviceData=null; // 返回给客户端的数据
System.out.println("英译汉服务器启动了......");
while (true){
// 读取socket中的数据,然后将数据封装到 packet_in 中
socket.receive(packet_in);
// 获取客户端输入的数据
buff_in=packet_in.getData();
// 将byte数组转换为字符串 需要去掉后面的空格
key=new String(buff_in,0,buff_in.length).trim();
// 根据map的key获取value
value=maps.get(key);
if(null == value){
value="默认值";
}
address=packet_in.getSocketAddress();
// 检查退出条件
if("down".equals(key)){
System.out.println("客户端输入的是:"+key);
reviceData="服务器关闭了,请重试".getBytes();
packet_out=new DatagramPacket(reviceData,reviceData.length,address);
socket.send(packet_out);
break;
}else {
System.out.println("客户端输入的是:"+key+",翻译后的结果是"+value);
// 构建服务端发送给客户端的数据
reviceData=("你输入的英文单词翻译成中文是:"+value).getBytes();
// 构建 packet_out 发送数据
packet_out=new DatagramPacket(reviceData,reviceData.length,address);
socket.send(packet_out);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("=====服务器关闭=====");
}
}
// 定义map集合,用来存放需要翻译的单词。
private static Map<String, String> maps = new HashMap<>();
// 向map中添加数据
static {
maps.put("dog", "狗");
maps.put("cat", "猫");
maps.put("fish", "鱼");
maps.put("bird", "鸟");
maps.put("pig", "猪");
}
}
运行方式
同时运行两个文件,见右上角,在控制台输入单词,如cat或者dog,现阶段只写了这几个翻译,你可以后续补充。
maps.put("dog", "狗");
maps.put("cat", "猫");
maps.put("fish", "鱼");
maps.put("bird", "鸟");
maps.put("pig", "猪");
待完成项目——可扩展项目
1、我们可以加入语音识别功能,读入英文,然后读出这个单词对应的中文
2、也可以导入数据库的方式去扩充。举个例子,这里我们实现的时候是通过HashMap存储数据,那么写一个数据库key对应value,就可以做到翻译单词的效果,是不是很神奇呢?
3、我们也可以融入网络的进一步知识,发布到网页上,那么需要注意的是如果布置在网页需要的一个重要前提是你需要学会序列化和反序列化进行类似于“传输和解码”。