《学习笔记Day 23》枚举类型详细介绍以及网络编程TCP、UDP的代码实现,附加print和println底层

一、枚举类型

(一)概念

1、就是描述对象个数是有限个的类型
2、声明一个枚举类型,使用关键字enum。枚举类型声明出来也是一个类型,编译过后也是一个.class文件

(二)自己实现枚举的第一种格式和使用枚举格式完成

1、自己实现:使用老汉式,在一个类中多定义几个对象就是枚举
2、枚举实现:
(1)使用enum关键字声明一个枚举类型
(2)在枚举类型中,声明罗列各个对象的名称
(3)在声明罗列各个对象时,对象之间使用逗号隔开,结束用分号结尾
(4)在枚举类型中的各个对象,叫做【枚举项】

//第一种自己实现枚举
public class meiju01 {

	public static void main(String[] args) {
		System.out.println(Week.MON);
	}
}

/*class Week{
	
	private Week() {}
	
	public static final Week MON = new Week();
	public static final Week TUE = new Week();
	public static final Week WED = new Week();
}*/

enum Week{
	MON,TUE,WED;
}

自己实现枚举的第二种格式和使用枚举格式完成

1、自己实现:加入一个成员变量
2、枚举实现:
(1)使用enum声明一个枚举类型
(2)在枚举类型中声明一个成员变量
(3)可以为成员变量提供get、set方法
(4)构造方法也可以提供,但必须是私有的
(5)在枚举类型的第一行,提供枚举项

public class meiju02 {

	public static void main(String[] args) {
		Week02 w = Week02.MON;
		System.out.println(w.getWeek());
	}
}

/*class Week02{
	private String week;
	private  Week02() {}
	public Week02(String week) {
		super();
		this.week = week;
	}
	public String getWeek() {
		return week;
	}
	public void setWeek(String week) {
		this.week = week;
	}
	
	public static final Week02 MON = new Week02("星期一");
	public static final Week02 THU = new Week02("星期二");
	public static final Week02 WED = new Week02("星期三");
}*/

enum Week02{
	MON("星期一"),THU("星期二"),WED("星期三");
	private String week;
	private Week02() {}

	public String getWeek() {
		return week;
	}

	public void setWeek(String week) {
		this.week = week;
	}

	private Week02(String week) {
		this.week = week;
	}
	
}

自己实现枚举的第三种格式和使用枚举格式完成

1、自己实现:在类中,再添加一个抽象方法
2、枚举实现:
(1)使用enum声明一个枚举类型
(2)在枚举类型中,声明一个成员变量
(3)提供成员变量的get、set方法
(4)枚举类型中定义一个抽象方法
(5)枚举项必须写在第一行,并且,枚举项使用匿名内部类的格式实现枚举类型中的抽象方法

package com.huzheng.demo;

public class meiju03 {

	public static void main(String[] args) {
		Week03 w = Week03.MON;
		
		w.show();
	}
}

/*abstract class Week03{
	private String week;
	
	private Week03() {}

	public Week03(String week) {
		super();
		this.week = week;
	}

	public String getWeek() {
		return week;
	}

	public void setWeek(String week) {
		this.week = week;
	}
	public static final Week03 MON = new Week03("星期一") {

		@Override
		public void show() {
			// TODO Auto-generated method stub
			System.out.println(getWeek());
		}
		
	};
	public static final Week03 TUE = new Week03("星期二") {

		@Override
		public void show() {
			// TODO Auto-generated method stub
			System.out.println(getWeek());
		}
		
	};
	public static final Week03 WED = new Week03("星期三") {

		@Override
		public void show() {
			// TODO Auto-generated method stub
			System.out.println(getWeek());
		}
		
	};
	
	public abstract void show();
}*/

enum Week03{
	MON("星期一"){

		@Override
		public void show() {
			// TODO Auto-generated method stub
			System.out.println(getWeek());
		}
		
	},TUE("星期二"){

		@Override
		public void show() {
			// TODO Auto-generated method stub
			System.out.println(getWeek());
		}
		
	},WED("星期三"){

		@Override
		public void show() {
			// TODO Auto-generated method stub
			System.out.println(getWeek());
		}
		
	};
	
	private String week;
	
	private Week03() {}

	private Week03(String week) {
		this.week = week;
	}

	public String getWeek() {
		return week;
	}

	public void setWeek(String week) {
		this.week = week;
	}
	
	public abstract void show();
}

(五)枚举类型的常用方法

1、所有使用enum关键字声明的枚举类型,全都是Enum类型的子类
2、常用方法:
(1)compareTo(E o) 比较两个枚举类型的顺序
(2)ordinal() 返回枚举常量的序数
(3)toString() 返回枚举项的名称,该方法在Enum类中已经重写过了,自定义的enum无法重写
(4)values() 返回一个数组,数组中的元素是枚举类型的所有枚举项(API中没有,在编译的时候由系统提供,是一个静态方法)

public class meiju04 {

public static void main(String[] args) {
		
		Week04 mon = Week04.MON;
		Week04 tue = Week04.TUE;
		Week04 wed = Week04.WED;
		System.out.println(mon.getName());
		
		System.out.println(mon.compareTo(tue));//-1
		System.out.println(mon.compareTo(wed));//-2
		
		System.out.println(mon.ordinal());//0
		System.out.println(tue.ordinal());//1
		System.out.println(wed.ordinal());//2
		
		System.out.println(mon.toString());//MON
		
		Week[] values = Week.values();
		
		for (Week week : values) {
			System.out.println(week);//MON TUE WED
		}
	}
}

enum Week04{
	MON("星期一"),TUE("星期二"),WED("星期三");
	private Week04() {}
	
	private String name;

	private Week04(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}

二、网络编程

网络编程:在已经拥有的完备成熟的网络系统中,在整个系统之上,使用网络进行编程,是针对应用层的设计活动。

(二)IP地址

1、IP地址是计算机在网络中的唯一标志
2、分类:
(1)IPV4:
1)构成:点分十进制的构成,由4个0~255的数组组成,来表示一个IP地址,4个字节即32位,能够表示约40亿个IP地址
2)四个字节中,有2个字节或者3个字节表示所在的子网
3)一个字节能表示0~255一共256个数字,但是不能全用
4)0表示子网网号:192.168.1.0就表示当前子网
5)255表示广播地址:广播地址发送的内容所在子网内的所有设备都能接收
6)特殊IP:127.0.0.1,表示本地回环地址,可以访问本机
7)相关命令:ipconfig查看当前网卡信息
8)ping:可以产看网络是否联通
(2)IPV6:
1)构成:由8组数字组成,每组数字都是4个16进制数字,每个数字有16中状态,32个数字,最多能表示16^32个IP地址
2)号称能给地球上每一粒沙子都给一个IP地址

(三)端口号

1、也是一个数字,用于标记一台电脑中的某个进程
2、端口号的取值范围:0~65535
3、意味着计算机中至多能够运行65536个进程,当程序运行的时候,计算机会分配一个独一无二的端口号给进程,我们通过端口号,就可以找到指定的进程,当进程结束时,端口号会被回收
4、分配:可以计算机随机分配,也可以用户指定
5、常用的端口号:
(1)操作系统:0~1024之间
(2)MySQL:3306
(3)Tomcat:8080
(4)QQ:4000
(5)Oracle:1521

(四)通信协议

1、用于定义通信双方在交互时,对信息的封装和解析的规则,就是协议
2、网络分层:分工,每一层都可以做独立的事情
(1)应用层:http、https协议等(规定数据如何封装以及解析)
(2)传输层:UDP协议、TCP协议(更多关注的是端对端的传输)
(3)网络层:IP地址(如何完成两台设备之间的传输)
(4)物理层:底层的硬件设备、数据完整性的校验

四、InetAddress类

1、InetAddress类的对象表示IP地址
2、对象获取方式:
(1)getByName(String host) 根据主机名称返回对象包含IP地址
(2)getByAddress(byte[] addr) 给定装有ip地址的数组,返回InetAddress类对象
(3)getAllByName(String host) 根据主机明后才能获取所有当前类型对象的数组
(4)getLocalHost() 获取本机的主机名和IP地址的对象
3、常用方法:
(1)getHostName() 获取主机名称
(2)getAddress() 获取IP地址的字节数组
(3)toString() 获取主机名称和IP地址的字符串表示形式

public class Demo08_InetAddress {

	public static void main(String[] args) throws UnknownHostException {
		InetAddress host = InetAddress.getLocalHost();
		
		System.out.println(host.getHostName());
		
		byte[] arr = host.getAddress();
		
		for (byte b : arr) {
			System.out.println(b);
		}
		
		System.out.println(host.toString());
	}

	public static void test1() throws UnknownHostException {
		InetAddress name = InetAddress.getByName("Zihuatanejo-PC");
		System.out.println(name);
		
		
		byte[] arr = {10, 10, 60, (byte) 177};
		InetAddress address = InetAddress.getByAddress(arr);
		System.out.println(address);
		
		InetAddress[] arr1 = InetAddress.getAllByName("Zihuatanejo-PC");
		for (InetAddress ele : arr1) {
			System.out.println(ele);
		}
		
		InetAddress host = InetAddress.getLocalHost();
		System.out.println(host);
	}
}

五、UDP协议和TCP协议

(一)概述

1、UDP协议和TCP协议都是传输层协议,都是端到端的协议
2、区别:
(1)UDP协议:面向无连接。像发短信、送信、寄快递等都是面向无连接。效率高,不安全,先发送的消息未必先收到。只区分发送端和接收端,而不像TCP协议区分客户端和服务器端。
(2)TCP协议:面向连接。打电话,先发送的消息一定先到达,安全,效率低,区分客户端和服务器端。在连接的时候,要经理三次握手。

(二)Socket编程

1、Socket:是两台计算机之间的通信端,类似生活中的快递站、邮局、码头
2、Socket也叫作套接字,套接字编程:网络编程、通信点编程
(1)UDP中要是用到的套接字是:DatagramSocket
(2)在TCP协议中,客户端要使用的是Socket,服务器端要是用的是ServerSocket和Socket

(三)UDP编程

1、要用到的通信点:DatagramSocket
2、构造方法:
(1)DatagramSocket() 不指定端口号,直接创建通信点对象,端口号随机分配,一般用于发送端
(2)DatagramSocket(int port) 指定端口号,创建通信点对象,一般用于接收端
3、成员方法:
(1)send(DatagramPacket p) 将一个数据报包进行发送
(2)receive(DatagramPacket p) 从通信点接收数据报包
4、数据报包:DatagramPacket
(1)构造方法:
1)DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 发送端
buf:要发送的数据的字节数组
offset:从数组的哪个位置开始发送数据
length:发送多少数据
address:IP地址
port:端口号
2)DatagramPacket(byte[] buf, int length) 接收端
(2)成员方法:
1)getData() 将接收到的byte[]数组从数据报包中解析出来
2)getLength() 返回发送了或者接收到的数据的长度

public class UDP_Send {

	public static void main(String[] args) throws IOException {
		//1.创建发送端的通信点对象
		DatagramSocket ds = new DatagramSocket();
		
		//2.准备数据报包
		byte[] buf = "闪电鞭".getBytes();
		int offset = 0;
		int length = buf.length;
		InetAddress address = InetAddress.getLocalHost();
		int port = 8848;
		
		DatagramPacket dp = new DatagramPacket(buf, offset, length, address, port);
		
		//3.通过通信点对象将数据报包发送出去
		ds.send(dp);
	}
}
public class UDP_Receive {
	
	public static void main(String[] args) throws IOException {
		//1.创建接收端的通信点对象
		DatagramSocket ds = new DatagramSocket(8848);
		
		//2.使用通信点对象接受网络中的数据
		byte[] buf = new byte[1024];
		int length = buf.length;
		DatagramPacket dp = new DatagramPacket(buf, length);
		
		ds.receive(dp);
		
		//3.从数据报包中将数据解析出来
		byte[] data = dp.getData();
		int len = dp.getLength();
		
		//4.打印数据
		System.out.println(new String(data, 0, len));
	}
}

(四)TCP编程

1、客户端要使用的是Socket,服务器端要是用的是ServerSocket和Socket
2、客户端和服务器端Socket对象的区别:
(1)客户端使用Socket的构造方法直接创建Socket对象
(2)服务器端不能直接使用Socket创建通信点对象,而是通过ServerSocket对象,从端口捕获客户端的响应,专门为这个客户端生成一个Socket对象
3、构造方法:
(1)Socket(InetAddress address, int port) 创建一个通信点对象,专门用于和制定IP的主机中指定的进程进行通信
(2)只要这个对象创建成功,就说明这个连接已经建立好了,也就说明客户端已经连接上了服务器端了,也就已经获取到了服务器返回的响应了
(3)创建对象的过程,就是在请求和服务器连接的过程
(4)ServerSocket(int port) 创建一个服务器通信点对象
(5)ServerSocket要配合accept()方法使用
(6)accept()方法是专门用于接收客户端请求,并且返回一个对应Socket对象的方法
4、传输操作:
(1)getOutputStream() 返回此套接字的输出流
(2)getInputStream() 返回此套接字的输入流
(3)一旦获取到IO流对象,就变成了以IO的方式传输
5、关系:
(1)客户端发送请求给服务器:客户端将请求从本机内存输出到网络,要用输出流
(2)服务器接收客户端传来的响应:服务器将网络中的请求读取到服务器的内存,要用输入流

public static void main(String[] args) throws UnknownHostException, IOException {
		//1.创建Socket对象,即客户端通信点对象
		Socket s = new Socket("127.0.0.1", 9999);
		
		//2.获取输出流对象,用于将请求从客户端内存传入网络
		OutputStream os = s.getOutputStream();
		
		//3.使用输出流将要传输的内容进行输出
		byte[] b = "松活弹抖闪电鞭".getBytes();
		os.write(b);
		
		s.close();
	}
}
public class TCP_Server {
	
	public static void main(String[] args) throws IOException {
		//1.创建服务器套接字对象,绑定到指定端口
		ServerSocket ss = new ServerSocket(9999);
		
		//2.调用accept方法捕获并且针对当前客户端创建Socket对象
		Socket s = ss.accept();
		
		//3.获取套接字的输入流对象,用于将网络中的请求,输入进服务器的内存中
		InputStream is = s.getInputStream();
		
		byte[] b = new byte[1024];
		int len = is.read(b);
		
		//4.将请求解析为文字并打印
		String request = new String(b, 0, len);
		
		System.out.println(request);
		
		s.close();
	}
}

(五)TCP加强

public class TCP_ClientPlus {
	
	public static void main(String[] args) throws UnknownHostException, IOException {
		//1.创建Socket对象
		Socket s = new Socket(InetAddress.getLocalHost(), 9898);
		
		//2.获取输入流和输出流对象
		//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		//3.键盘录入要发送的请求,通过高效缓冲字符输出流发送出去
		Scanner sc = new Scanner(System.in);
		
		String request = sc.nextLine();
		pw.println(request);
		
		//4.通过高效缓冲字符输入流用于读取请求
		String response = br.readLine();
		
		System.out.println(response);
		
		s.close();
	}
}
public class TCP_ServerPlus {
	
	public static void main(String[] args) throws IOException {
		
		//1.创建ServerSocket对象用于监听端口号
		ServerSocket ss = new ServerSocket(9898);
		
		while (true) {
			//2.调用accept方法获取请求并建立连接
			Socket s = ss.accept();
			
			new Thread() {

				@Override
				public void run() {

					try {
						//3.获取流对象
						BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
						PrintWriter pw = new PrintWriter(s.getOutputStream(), true);

						//4.输入流读取请求
						String request = br.readLine();

						System.out.println(request);

						//5.键盘录入响应并通过流进行返回
						Scanner sc = new Scanner(System.in);

						String response = sc.nextLine();
						pw.println(response);

						s.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}.start();
		}
	}
}

print 和 println 底层都使用write方法,只是 println 多加了个‘ \n ’ ,在PrintWrite类中【PrintWriter(OutputStream out, boolean autoFlush) 通过现有的 OutputStream 创建新的 PrintWriter】 在Java中只有println才可以刷新输出缓冲区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿福真的不想掉头发

大爷?赏点?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值