学习网络编程练习时遇到的几个比较奇怪的现象,记录一下
在练习网络编程的时候发现几个比较奇怪的现象,记录一下
我先把代码放上来
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里面
对于收到的数据进行编码时
使用new String(data) 构造方法,文本中显示效果如下
如果改用new String(data,0,data.length)这个构造方法,显示效果就没有问题
我做了一个测试
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(); }
}
在这个测试中,不管是控制台输出语句,还是直接输出到文件中,效果都是正常的
控制台输出效果:
文本中输出效果:
关于下面这两种构造方法,看不出来什么区别,下面的最终调用的也是上面的这个方法
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里面,对要发送的数据进行解码的时候
如果我使用这条语句
bytes = message.getBytes();
那么网络调试助手里面收到的消息,英文字符完全正常,中文字符出现丢字现象,还出现 ?
当时当我手动指定编码方式为UTF-8之后,异常现象消失
也就是改写成这个语句
bytes = message.getBytes(“UTF-8”);
但是我的IDEA里面字符相关的设置默认就是UTF-8,没有选择过其他编码方式
以上两个现象很奇怪,想不明白
这是我IDEA里面编码相关的设置,全部都是UTF-8