编码及UDP总结

来源:互联网 发布:广告公司需要什么软件 编辑:程序博客网 时间:2024/05/23 17:54

一、编码表的由来:计算机只能识别二进制数据,早期由来是电信号,为了方便计算机,让它识别各个国家的文字,就将各个国家的文字用数字表示,就将各个国家的文字用数字来表示,并一一对应,这就形成编码表。

ASCII:美国标准信息交换码,用一个字节的7位表示。

ISO8859-1:拉丁码表,用一个字节的8位表示。

GB2312:中文编码表,用两个字节完成,每个字节都是负数,也就是说最高位是1.

GBK:中国的中文编码表升级,融合了更多的中文字符号,也是用两个字节完成,第一个字节是负数,第二个字节不一定是负数。

Unicode:国际标准码,融合了多种文字,两个字节表示,java语言使用的就是unicode

UTF-8:最多用三个字节来表示一个字符。

文字编解码:

编码:字符串------>字节数组  Str.getBytes();

解码:字节数组------->字符串  new String(buf[])

切割字符串Demo:

public static void main(String[] args) throws IOException {

你好:-60,-29,-70,-61 java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符。 但对应的字节数不同,一个汉字占两个字节。 定义一个方法,按照最大的字节数来取子串。如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个, 那么半个就要舍弃。如果去四个字节就是“ab你”,取五个字节还是“ab你”思路: 1,需要指定码表,默认是GBK2,咋判断中文的一半呢?对于GBK而言,中文的编码是两个字节,两个字节都是负数。但是在GBK的码表中,有的中文是第一个字节负数,第二字节是正数。思想一样好用。 通过判断最后一个字节是否是负数就可以了吗?不,如果最后一个截取的字节是负数,还需要往回判断负数的个数。 如果是奇数个,舍弃,如果是偶数个,不舍。

// String s1 = "";

// byte[] b1 = s1.getBytes("gbk");

// for(byte b : b1){

// System.out.println(b);

// }

String str = "ab你好cd谢谢e琲琲f";

// byte[] buf = str.getBytes("gbk");

// for (int x = 0; x < buf.length; x++) {

// String s = cutStringByByteLen(str, (x+1));

// System.out.println("截取"+(x+1)+"个,结果是:"+s);

// }

byte[] buf = str.getBytes("UTF-8");

for (int x = 0; x < buf.length; x++) {

String s = cutStringByByteLenU8(str, (x + 1));

System.out.println("截取" + (x + 1) + "个,结果是:" + s);

}

}

public static String cutStringByByteLenU8(String str, int len) throws UnsupportedEncodingException {

// 1,按照指定的码表将字符串编码。获取对应的字节数组。

byte[] buf = str.getBytes("UTF-8");

int count = 0;

// 2,对数组进行遍历。

for (int x = len - 1; x >= 0; x--) {

if (buf[x] < 0)

count++;

else

break;

}

if (count % 3 == 0)

return new String(buf, 0, len, "utf-8");

else if(count%3==1)

return new String(buf, 0, len - 1, "UTF-8");

return  new String(buf, 0, len - 2, "UTF-8");

}

public static String cutStringByByteLen(String str, int len)

throws UnsupportedEncodingException {

// 1,按照指定的码表将字符串编码。获取对应的字节数组。

byte[] buf = str.getBytes("gbk");

int count = 0;

// 2,对数组进行遍历。

for (int x = len - 1; x >= 0; x--) {

if (buf[x] < 0)

count++;

else

break;

}

if (count % 2 == 0)

return new String(buf, 0, len, "GBK");

return new String(buf, 0, len - 1, "GBK");

}

二:IP地址:InetAddress

网络中设备的标识,不易记忆,可用主机名。本地回环地址:127.0.0.1  主机名:localhost

端口号:用于标识进程的逻辑地址,不同进程的标识。

有效端口:0~65535,其中0~1024系统使用或保留端口。

传输协议:通讯的规则,常见协议:TCPUDP

UDP:将数据及源和目的封装成数据包中,不需要建立连接,每个数据报的大小在限制在64k内,因无连接,是不可靠协议、不需要建立连接,速度快。

TCP:建立连接,形成传输数据的通道。在连接中进行大数据量传输,通过三次握手完成连接,是可靠协议,必须建立连接,效率会稍低。

Socket就是为网络服务提供的一种机制。通信的两端都有Socket。网络通信其实就是Socket间的通信。数据在两个Socket间通过IO传输。

获取IP对象和主机

//获取本地主机ip对象。

// InetAddress ip = InetAddress.getLocalHost();

InetAddress ip = InetAddress.getByName("192.168.1.252");

//获取ip对象中的ip地址字符串。或者ip地址对应的主机名称。

System.out.println(ip.getHostAddress());

System.out.println(ip.getHostName());

通过udp协议创建一个发送端

/*

 * 通过udp协议创建一个发送端。

 * 思路:

 * 1,应该有可以通过该协议传输数据的对象。先有udp服务。

 * 2,有数据,并将数据封装到数据包,并在包上明确目的地址。

 * 3,通过udp服务将这个数据包发出去。

 * 4,关闭资源。

 */

System.out.println("udp 发送端开启");

//1,创建udp socket服务.

DatagramSocket ds = new DatagramSocket(8888);

//2,明确数据,并将数据封装到数据包中。

String str = "udp演示,哥们来了";

byte[] buf = str.getBytes();

DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.252"),10000);

//3,将数据包通过socket服务发送。

ds.send(dp);

//4,关闭资源。

ds.close();

System.out.println("udp 发送端关闭");

通过udp协议创建一个接受端

/*

 * udp的接收端:

 * 思路:

 * 1,创建udpsocket服务。

 * 2,接收数据并存储到数据包中,存储到数据包中的目的是为了解析接收到的数据。

 * 3,将解析到的数据打印到显示器。

 * 4,关闭服务。

 */

System.out.println("udp 接收端开启");

//1,创建udpsocket服务。用于接收端,一定要指定端口,因为必须要明确从哪个端口来的数据是这个应用程序所能解析的。

//简单说:接收端必须监听一个端口。

DatagramSocket  ds = new DatagramSocket(10000);

//2,接收数据到数据包中。

byte[] buf = new byte[1024];

DatagramPacket dp = new DatagramPacket(buf,buf.length);

ds.receive(dp);

//3,解析数据包中的具体数据。

String ip = dp.getAddress().getHostAddress();

int port = dp.getPort();

String text = new String(dp.getData(),0,dp.getLength());

System.out.println(ip+":::"+port+":::::"+text);

//4,关闭资源。

ds.close();

System.out.println("udp 接收端关闭");简易聊天室设计:

Send.java

public class Send implements Runnable {

private DatagramSocket sendSocket;

public Send(DatagramSocket sendSocket) {

this.sendSocket = sendSocket;

}

public void run() {

try{

BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); 

String line=null;

while((line=bufr.readLine())!=null){;

byte[] but=line.getBytes();

DatagramPacket dp=new DatagramPacket(but, but.length,InetAddress.getByName("192.168.1.255"),10200);

sendSocket.send(dp);

if("886".equals(line))

break;

}

sendSocket.close();

}catch(IOException e){

}

}

}

Rece.java

public class Rece implements Runnable {

private DatagramSocket receSocket;

public Rece(DatagramSocket receSocket) {

this.receSocket = receSocket;

}

public void run() {

try{

while(true)

{

byte[] but=new byte[1024];

DatagramPacket dp=new DatagramPacket(but, but.length);

receSocket.receive(dp);

String ip=dp.getAddress().getHostAddress();

int port=dp.getPort();

String text=new String(dp.getData(),0,dp.getLength());

System.out.println(ip+":"+port+";;"+text);

if("886".equals(text)){

System.out.println("此人离开聊天室");

break;

}

}

}catch(IOException e){

}

}

}

主线程UDPChatTestJava

public static void main(String[] args) throws IOException {

DatagramSocket sendSocket=new DatagramSocket(10000);

DatagramSocket receSocket=new DatagramSocket(10200);

new Thread(new Send(sendSocket)).start();

new Thread(new Rece(receSocket)).start();

}

原创粉丝点击