前言:今天看视频敲代码学习UDP时,出现了一些类型转换问题,我们往下看
代码一如下:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//UDP:不需要等服务器启动才运行,直接运行客户端不会报错,相当于发短信
/*
TCP:
需要连接服务器,如果服务器没启动,客户端直接运行,会报错(ConnectException),相当于打电话,两者要同时在线。(三次握手,四次挥手)
*/
public class UDPClientDemo01 {
public static void main(String[] args) throws Exception{
//1.建立一个Socket
DatagramSocket socket = new DatagramSocket();
//2.建立一个包
String msg = "你好啊,服务器";
InetAddress localhost = InetAddress.getLocalHost();
int port = 9000;
//数据,数据的长度起始,发送给谁
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.length(),localhost,port);
//3.发送包
socket.send(packet);
//4.关闭流
socket.close();
}
}
代码二如下:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//需要等待客户端的连接
public class UDPServerDemo01 {
public static void main(String[] args) throws Exception {
//开放端口
DatagramSocket socket = new DatagramSocket(9000);
//接收数据
byte[] buffer = new byte[1024];
DatagramPacket packet1 = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet1);//阻塞接收
System.out.println(new String(packet1.getData(),0,packet1.getLength()));
//关闭流
socket.close();
}
}
我们先运行代码2,在运行代码1,代码2的控制台显示如下结果:
你好�
"你好"后面出现了乱码现象,我当即反应是去查看编译器有没有设置utf-8编码,查了下,编译器设置了utf-8编码,花了十分钟左右才找到问题,在代码1的下面这句代码出现了问题。
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.length(),localhost,port);
这是因为String类型转换成byte类型数组时字节数的问题
我们在代码1输出一下两者的长度
代码如下:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClientDemo01 {
public static void main(String[] args) throws Exception{
//1.建立一个Socket
DatagramSocket socket = new DatagramSocket();
//2.建立一个包
String msg = "你好啊,服务器";
InetAddress localhost = InetAddress.getLocalHost();
int port = 9000;
//输出转换成byte数组的长度
System.out.println(msg.getBytes().length);
//输出String的长度
System.out.println(msg.length());
//数据,数据的长度起始,发送给谁
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.length(),localhost,port);
//3.发送包
socket.send(packet);
//4.关闭流
socket.close();
}
}
结果:
19
7
为什么String类型转换成byte类型数组,长度由7变19呢?原因如下:
英文字母和中文汉字在不同字符集编码下的字节数
英文字母:
字节数 : 1;编码:GB2312
字节数 : 1;编码:GBK
字节数 : 1;编码:GB18030
字节数 : 1;编码:ISO-8859-1
字节数 : 1;编码:UTF-8
字节数 : 4;编码:UTF-16
字节数 : 2;编码:UTF-16BE
字节数 : 2;编码:UTF-16LE
中文汉字:
字节数 : 2;编码:GB2312
字节数 : 2;编码:GBK
字节数 : 2;编码:GB18030
字节数 : 1;编码:ISO-8859-1
字节数 : 3;编码:UTF-8
字节数 : 4;编码:UTF-16
字节数 : 2;编码:UTF-16BE
字节数 : 2;编码:UTF-16LE
看到这里,我们大概能明白了,代码1的字符串中有六个汉字和一个逗号,刚好长度为7,转换成byte数组时,因为是utf-8编码,一个汉字对应3个字节,所以19=3*6+1。我们下面这个代码,用的是字符串的长度,起始位置从0到7,而转换成byte类型数组是的长度为19,这就意味着7到19的数据没有读到,读到了"你好"6个字节加上一个字节的乱码,如果增加两个字节(即读取0到9),则控制台会输出"你好啊"。
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.length(),localhost,port);
我们只要将代码改成这样就不会出现乱码问题了:
DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);