记录下学习发现几个比较奇怪的现象
我先把代码放上来
package com.atguigu.exercise.receiveandsend;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.util.Scanner;
/**
* @Description:
* @Author: Gavin
* @Date: 4/6/2023 6:15 PM
* receive and send demo */public class ReceiveAndSend {
public static void main(String[] args) throws IOException {
// 先创建DatagramSocket
DatagramSocket socket = new DatagramSocket(9000);
// 再来创建一个writter流,用来把接收到的聊天记录输出到文件里面
FileWriter fw = new FileWriter("testIO/chatLog.txt", true);
// 创建接受的thread
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
byte[] arr = new byte[1024];
DatagramPacket packet = new DatagramPacket(arr, arr.length);
try {
socket.receive(packet);
} catch (IOException e) {
throw new RuntimeException(e);
}
// 将接收到的packet转换成信息
byte[] data = packet.getData();
int length = packet.getLength();
String message = new String(data);
//message = new String(data,0,data.length);
String receiveMessage = "接受到来自:" + packet.getAddress() + ":" + packet.getPort() + "的信息:" + message + "\n";
// 读取信息
try {
fw.write(receiveMessage);
fw.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (message.equals("886")) {
break;
}
}
}
}, "receiver").start();
Scanner input = new Scanner(System.in);
// System.out.print("请输入对方的IP地址:");
// String ip = input.next(); String ip = "192.168.20.77";
// System.out.print("请输入对方的端口:");
// int port = input.nextInt(); int port = 9090;
InetAddress byName = InetAddress.getByName(ip);
// 创建发送的thread
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.print("请输入你想发送的内容:");
String message = input.next();
// 将message转成二进制
byte[] bytes = new byte[0];
try {
bytes = message.getBytes("UTF-8");
//bytes = message.getBytes();
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// 创建1个packet
DatagramPacket packet = new DatagramPacket(bytes, bytes.length, byName, port);
try {
socket.send(packet);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (message.equals("886")) {
break;
}
}
}
}, "sender").start();
}
}
在receiver Thread里面
对于收到的数据进行编码时
[外链图片转存中…(img-P3sYSAxP-1680786176459)]
使用new String(data) 构造方法,文本中显示效果如下
[外链图片转存中…(img-jS1et7li-1680786176460)]
如果改用new String(data,0,data.length)这个构造方法,显示效果就没有问题
[外链图片转存中…(img-E3UKBC2b-1680786176461)]
我做了一个测试
package com.atguigu.exercise;
import java.io.FileWriter;
import java.io.IOException;
/**
* @Description:
* @Author: Gavin
* @Date: 4/6/2023 8:13 PM
*/public class Test01 {
public static void main(String[] args) throws IOException {
String str = "这是一条测试语句";
//先解码
byte[] bytes = str.getBytes();
//再来编码
String s1 = new String(bytes);
//第二种编码方式
String s2 = new String(bytes,0,bytes.length);
System.out.println("s1 = "+s1);
System.out.println("s2 = "+s2);
FileWriter write = new FileWriter("testIO/testString.txt");
write.write("s1 = "+s1);
write.flush();
write.write("\ns2 = "+s2);
write.flush();
}
}
在这个测试中,不管是控制台输出语句,还是直接输出到文件中,效果都是正常的
控制台输出效果:
[外链图片转存中…(img-BjgEsHg6-1680786176462)]
文本中输出效果:
[外链图片转存中…(img-oN5Iye8Q-1680786176462)]
关于下面这两种构造方法,看不出来什么区别,下面的最终调用的也是上面的这个方法
public String(byte[] bytes, int offset, int length) {
this(bytes, offset, length, Charset.defaultCharset());
}
public String(byte[] bytes) {
this(bytes, 0, bytes.length);
}
在sender Thread里面,对要发送的数据进行解码的时候
[外链图片转存中…(img-WT4ibrD4-1680786176463)]
如果我使用这条语句
bytes = message.getBytes();
那么网络调试助手里面收到的消息,英文字符完全正常,中文字符出现丢字现象,还出现 ?
[外链图片转存中…(img-H7b7MQkU-1680786176464)]
当时当我手动指定编码方式为UTF-8之后,异常现象消失
也就是改写成这个语句
bytes = message.getBytes(“UTF-8”);
但是我的IDEA里面字符相关的设置默认就是UTF-8,没有选择过其他编码方式
这是我IDEA里面编码相关的设置,全部都是UTF-8
[外链图片转存中…(img-kwK8spEY-1680786176465)]