黑马程序员 网络(UDP传输和TCP传输)及反射

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------



一.IP地址


每个设备在网络中的唯一标识

    每台网络终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址。

    ipconfig:查看本机IP

    ping:测试连接

    本地回路地址:127.0.0.1255.255.255.255是广播地址

    IPv4:4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿。2011年初已经用尽。

    IPv6:8组,每组4个16进制数。

    1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f

    1a2b::aaaa:0000:0000:0000:aabb:1f2f

    1a2b:0000:aaaa::aabb:1f2f

    1a2b:0000:aaaa::0000:aabb:1f2f

    1a2b:0000:aaaa:0000::aabb:1f2f

二.端口号

每个程序在设备上的唯一标识

    每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器上,还要明确发到哪个程序。

    端口号范围从0-65535

    编写网络应用就需要绑定一个端口号,尽量使用1024以上的,1024以下的基本上都被系统程序占用了。

    常用端口

    mysql: 3306

    oracle: 1521

    web: 80

    tomcat: 8080

    QQ: 4000

    feiQ: 2425

三.网络协议

为计算机网络中进行数据交换而建立的规则、标准或约定的集合。

    UDP

    面向无连接,数据不安全,速度快。不区分客户端与服务端。

    TCP

      面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。

    三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据

四.Socket

通信的两端都有Socket。

    网络通信其实就是Socket间的通信。

    数据在两个Socket间通过IO流传输。

    Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和port。


五.UDP传输

    1.发送

    创建DatagramSocket, 随机端口号

    创建DatagramPacket, 指定数据, 长度, 地址, 端口

    使用DatagramSocket发送DatagramPacket

    关闭DatagramSocket

    2.接收

    创建DatagramSocket, 指定端口号

    创建DatagramPacket, 指定数组, 长度

    使用DatagramSocket接收DatagramPacket

    关闭DatagramSocket

    从DatagramPacket中获取数据

    3.接收方获取ip和端口号

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

    int port = packet.getPort();

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;

public class Demo2_Send {

	/**
	 * 1.发送 创建DatagramSocket, 随机端口号 创建DatagramPacket, 指定数据, 长度, 地址, 端口
	 * 使用DatagramSocket发送DatagramPacket 关闭DatagramSocket
	 * 
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		// String str = "我读书少,你不要骗我";
		DatagramSocket socket = new DatagramSocket(); // 创建Socket对象,相当于创建码头
		Scanner sc = new Scanner(System.in);
		while (true) {
			String line = sc.nextLine();
			if("quit".equals(line))
				break;
			DatagramPacket packet = // 创建Packet对象,相当于创建集装箱
			new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("127.0.0.1"), 6666);
			socket.send(packet); // 发送集装箱
		}
		socket.close();
	}

}

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Demo2_Receive {

	/**
	 * 2.接收
		创建DatagramSocket, 指定端口号
		创建DatagramPacket, 指定数组, 长度
		使用DatagramSocket接收DatagramPacket
		关闭DatagramSocket
		从DatagramPacket中获取数据
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		DatagramSocket socket = new DatagramSocket(6666);	//创建Socket对象,相当于创建码头
		DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//创建Packet对象,相当于创建集装箱接货
		while(true) {
			socket.receive(packet);											//接收数据
			byte[] arr = packet.getData();									//获取数据
			int len = packet.getLength();									//获取有效的字节个数
			String ip = packet.getAddress().getHostAddress();		//获取ip地址
			System.out.println(ip + ":" + new String(arr,0,len));
		}
	}

}


多线程

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Demo3_MoreThread {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new Receive().start();
		new Send().start();
	}

}

class Receive extends Thread {
	public void run() {
		try {
			DatagramSocket socket = new DatagramSocket(6666);	//创建Socket对象,相当于创建码头
			DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//创建Packet对象,相当于创建集装箱接货
			while(true) {
				socket.receive(packet);											//接收数据
				byte[] arr = packet.getData();									//获取数据
				int len = packet.getLength();									//获取有效的字节个数
				String ip = packet.getAddress().getHostAddress();		//获取ip地址
				System.out.println(ip + ":" + new String(arr,0,len));
			}
		} catch (Exception e) {
			
			e.printStackTrace();
		} 
	}
}

class Send extends Thread {
	public void run() {
		try {
			DatagramSocket socket = new DatagramSocket(); // 创建Socket对象,相当于创建码头
			Scanner sc = new Scanner(System.in);
			while (true) {
				String line = sc.nextLine();
				if("quit".equals(line))
					break;
				DatagramPacket packet = // 创建Packet对象,相当于创建集装箱
				new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.33.186"), 6666);
				socket.send(packet); // 发送集装箱
			}
			socket.close();
		} catch (Exception e) {
			
			e.printStackTrace();
		} 
	}
}

六.TCP传输

1.客户端

       创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器

       调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流

       输入流可以读取服务端输出流写出的数据

       输出流可以写出数据到服务端的输入流


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Demo2_Client {

	/**
	 *1.客户端
		创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器
		调用Socket的getInputStream()和getOutputStream()方法获取和服务端相连的IO流
		输入流可以读取服务端输出流写出的数据
		输出流可以写出数据到服务端的输入流
	 * @throws Exception 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws Exception {
		Socket socket = new Socket("127.0.0.1", 12345);		//创建客户端
		/*InputStream is = socket.getInputStream();			//获取输入流
		OutputStream os = socket.getOutputStream();			//获取输出流
		
		byte[] arr = new byte[1024];
		int len = is.read(arr);						//读取服务器发送的数据
		System.out.println(new String(arr,0,len));
		
		os.write("学习挖掘机哪家强".getBytes());			//将数据写给服务器
*/		
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//包装字节输入流
		//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		PrintStream ps = new PrintStream(socket.getOutputStream());//包装字节输出流
		System.out.println(br.readLine());				//读取服务器写过来的内容
		ps.println("我要报名就业班");						//将数据写给服务器
		System.out.println(br.readLine())
		ps.println("不学了");
		//bw.write("我要报名就业班");
		socket.close();
	}

}

2.服务端

       创建ServerSocket(需要指定端口号)

       调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket

       调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流

       输入流可以读取客户端输出流写出的数据

       输出流可以写出数据到客户端的输入流

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo2_Server {

	/**
	 * 2.服务端
		创建ServerSocket(需要指定端口号)
		调用ServerSocket的accept()方法接收一个客户端请求,得到一个Socket
		调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流
		输入流可以读取客户端输出流写出的数据
		输出流可以写出数据到客户端的输入流
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		ServerSocket server = new ServerSocket(54321);			//创建服务端,绑定54321端口
		Socket socket = server.accept();						//接受客户端请求
		/*InputStream is = socket.getInputStream();				//获取字节输入流
		OutputStream os = socket.getOutputStream();				//获取字节输出流
		
		os.write("百度一下你就知道".getBytes());				//将内容写给客户端
		
		byte[] arr = new byte[1024];
		int len = is.read(arr);							//从客户端读取数据
		System.out.println(new String(arr,0,len));				*/
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//包装字节输入流
		//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		
		//bw.write("欢迎咨询传智播客");
		PrintStream ps = new PrintStream(socket.getOutputStream());//包装字节输出流,因为里面有一个println的方法
		ps.println("欢迎咨询传智播客");						//将字符串写到客户端
		System.out.println(br.readLine());				//读取客户端发过来的信息
		ps.println("报满了,等下一期吧");
		System.out.println(br.readLine());
		server.close();
		socket.close();
	}

}

创建多线程的服务端,可以不断的向服务端访问

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo3_MoreThread {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(12345);
		while(true) {
			final Socket socket = server.accept();			//不断的接收客户端的请求
			new Thread() {
				public void run() {
					try {
						BufferedReader br = 
						new BufferedReader(new InputStreamReader(socket.getInputStream()));
						PrintStream ps = new PrintStream(socket.getOutputStream());
						
						ps.println("欢迎咨询黑马程序员");
						System.out.println(br.readLine());
						ps.println("不一万就业不给一分钱");
						System.out.println(br.readLine());
						ps.println("不学拉到");
						socket.close();
					} catch (Exception e) {
						
						e.printStackTrace();
					}
				}
			}.start();
		}
	}

}

七.反射

1.Class

       .class文件加载到内存中就是一个Class对象

       获取Class对象的方式有3种:

       Scanner sc = newScanner("xxx.txt");

           Class.forName(sc.nextLine());

           类名.class

           对象.getClass()

import cn.itcast.bean.Person;

public class Demo1_Reflect {

	/**
	 * @param args
	 * @throws ClassNotFoundException 
	 */
	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> clazz1 = Class.forName("cn.itcast.bean.Person");
		Class<?> clazz2 = Person.class;
		
		Person p = new Person();
		Class<?> clazz3 = p.getClass();
		
		System.out.println(clazz1 == clazz2);
		System.out.println(clazz2 == clazz3);
	}

}

2.Constructor

       Class类的newInstance()方法是使用该类无参的构造函数创建对象, 如果一个类没有无参的构造函数, 就不 能这样创建了

       可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数

       然后再调用Constructor类的newInstance("张三",20)方法创建对象

import java.lang.reflect.Constructor;

import cn.itcast.bean.Person;

public class Demo3_Constructor {

	/*
	  @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		Class<?> clazz = Class.forName("cn.itcast.bean.Person");
		/*Person p = (Person) clazz.newInstance();
		System.out.println(p);*/
		Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数
		Person p = (Person) con.newInstance("张三",23);					//创建对象
		System.out.println(p);											//打印对象
	}

}

3.Field

       Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以用getDeclaedField("name")方法获取

       通过set(obj, "李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限

       用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

import cn.itcast.bean.Person;

public class Demo4_Field {

	
	
	public static void main(String[] args) throws Exception {
		Class<?> clazz = Class.forName("cn.itcast.bean.Person");
		Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数
		Person p = (Person) con.newInstance("张三",23);					//创建对象
		
		/*Field f = clazz.getField("name");
		System.out.println(f);*/
		Field f = clazz.getDeclaredField("name");						//暴力反射
		f.setAccessible(true);											//去除权限
		f.set(p, "李四");
		System.out.println(p);
	}

4.Method

       Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中 的指定方法

       调用invoke(Object,Object...)可以调用该方法

       Class.getMethod("eat")invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import cn.itcast.bean.Person;

public class Demo5_Method {

	/**
	 *4.Method
		Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法
		调用invoke(Object, Object...)可以调用该方法
		Class.getMethod("eat") invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		Class<?> clazz = Class.forName("cn.itcast.bean.Person");
		Constructor con = clazz.getConstructor(String.class,int.class);//获取有参的构造函数
		Person p = (Person) con.newInstance("张三",23);					//创建对象
		
		Method m = clazz.getMethod("eat");
		m.invoke(p);
		
		Method m2 = clazz.getMethod("eat", int.class);
		m2.invoke(p, 10);
	}

}














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值