常见的客户端和服务端有哪些呢?
客户端:浏览器
服务端:Tomcat
如果请求图片的网页,请求的次数很多,有多少资源html文件,图片文件,css文件,js文件;就需要请求多少次
浏览器中当然也是内容如socket一样的客户端程序
用java模拟:Socket socket=new Socket("192.168.12.135",8080);
可是浏览器到底向服务器发送了什么样的请求呢?
怎么验证?将tomacat服务器换掉。自定义一个服务器接收浏览器发送的数据
这样就知道浏览器发送的是什么
1、自定义服务器
浏览器给服务器发送的信息如下:
192.168.1.136...connected
GET / HTTP/1.1 //请求方式//请求的路径//http的协议版本
//http协议的请求头消息
//请求消息中的属性信息
Host: 192.168.1.136:9090
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36//用户代理接受的平台
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8//接收的解析文件的格式
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8//支持的语言
空格
模拟浏览器获取网页信息
网络架构
两种:
C/S client server
特点:
1、客户端和服务器都需要编写
2、客户端需要维护
3、客户端可以分担部分运算
如果 大型运算,比如网络游戏
B/S brower server
特点:
1、只需要编写服务端,客户端其实就是已有的服务器
2、客户端不需要维护的
3、预算全在服务器端
模拟服务器
package cn.network.demo;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MYBrowser {
/**
* @param args
* 模拟浏览器,发送一些http的消息给tomcat服务器,并获取服务器反馈的信息
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket=new Socket("192.168.1.136", 18080);
// 获取输出流,给服务器发送数据
PrintWriter out=new PrintWriter(socket.getOutputStream(),true);
out.println("GET /lala/hello.html HTTP/1.1");
out.println("Accept: */*");
out.println("Host: 192.168.1.136:9090");
out.println("Connection: close");//keep-alive,服务器会一直等着发数据,close发送一次就停止了
// out.println("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
// out.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
// out.println("Accept-Encoding: gzip, deflate, sdch");
// out.println("Accept-Language: zh-CN,zh;q=0.8");
out.println();
InputStream in=socket.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
String strs=new String(buf, 0, len);
System.out.println(strs);
socket.close();
}
}
反射
package cn.network.demo;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class RelectDemo2 {
/**
* @param args
* 演示如何根据给定名称取到指定的class对象后建立该类的对象呢?
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// getObjectDemo1();
getObjectDemo2();
}
/**
* @throws ClassNotFoundException
* @throws SecurityException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InstantiationException
*
*/
private static void getObjectDemo2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
/*
万一给定类中没有空参数呢?
可以先获取指定的构造函数,再通过该构造函数进行实例化
通过Class获取指定 构造函数,比如带两个参数
*/
String className="cn.network.demo.Person";
Class class1=Class.forName(className);
Constructor constructor=class1.getConstructor(String.class,int.class);//参数传递的是类型对象
System.out.println(constructor);
Object object=constructor.newInstance("李四",46);
}
/**
* @throws ClassNotFoundException
* @throws ReflectiveOperationException
* @throws InstantiationException
* @throws Exception
* @throws NoSuchMethodException
*
*/
private static void getObjectDemo1() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, Exception {
String className="cn.network.demo.Person";
Class class1=Class.forName(className);
Object object=class1.newInstance();//创建一个Person对象默认的调用该类的空参数构造函数
//记住了,一般被反射的类通常都有空参数的构造函数
}
}
package cn.network.demo;
public class ReflectDemo {
/**
* @param args
* 反射技术:动态的获取类以及类中的成员,并可以调用该类成员
* 以前是有什么类,就new什么对象。没有类,给什么类就创建什么对象
*
* 无论new什么对象,都需要先获取字节码文件
* 如何获取呢?发现java已对字节码文件进行了描述用的class类完成的
*
* 如何获取一个字节码文件的对象呢?
* 方式一: Object getClass()方法
*
* 方式二:所有的数据类型都有自己对对应的class对象。表示方式很简单
* 每一个数据类型都有一个默认的静态的属性。.class 用该属性就可以获取到自字节码文件对象
* 虽然不用对象调用了,还是要用到具体的类调用静态属性
*
* 方式三:在Class类中找到了forName方法,通过名称就可以获取对应的字节码文件对象
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {
// methodDemo_1();
// methodDemo_2();
methodDemo_3();
}
/**
* @throws ClassNotFoundException
*
*/
private static void methodDemo_3() throws ClassNotFoundException {
String className="cn.network.demo.Person";//一定要传对类名,要完整版!
Class class1=Class.forName(className);
System.out.println(class1);
}
/**
*
*/
private static void methodDemo_2() {
Class class1=Person.class;
// int.class
Class class2=Person.class;
System.out.println(class1==class2);
}
// 获取class独享的方式一
public static void methodDemo_1() {
// 调用getclass先有对象
Person person1=new Person();
Person person2=new Person();
Class class1=person1.getClass();
Class class2=person2.getClass();
System.out.println(class1);
System.out.println(class1==class2);//两个类相同
}
}
package cn.network.demo;
import java.lang.reflect.Field;
public class ReflectFieldDemo {
/**
* @param args
* 获取类中的成员
* 反射字段
* @throws ClassNotFoundException
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static void main(String[] args) throws Exception {
getField();
}
/**
* @throws ClassNotFoundException
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws InstantiationException
*
*/
private static void getField() throws Exception {
String className="cn.network.demo.Person";
Class class1=Class.forName(className);
//获取age字段
Field field1=class1.getField("age");//只能拿到公有的
Field field2=class1.getDeclaredField("name");//能拿到公有和私有的,但是不包括继承的
System.out.println(field1);
System.out.println(field2);
// 要对非静态的字段操作必须有对象
Object object=class1.newInstance();
// 使用父类的方法将访问权限检查能力取消
field2.setAccessible(true);//暴力访问
field2.set(object, "小王");
System.out.println(field2.get(object));
}
}
package cn.network.demo;
import java.lang.reflect.Method;
public class ReflectMethodDemo {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// getMethodDemo();
getMethodDemo2();
getMethodDemo3();
}
/**
*
*/
private static void getMethodDemo3() throws Exception{
String className="cn.network.demo.Person";
Class class1=Class.forName(className);
Method method=class1.getMethod("paramShow", String.class,int.class);
Object object=class1.newInstance();
method.invoke(object,"张三",30);
}
/**
* 反射方法,静态,无参数的show方法
*/
private static void getMethodDemo2() throws Exception{
String className="cn.network.demo.Person";
Class class1=Class.forName(className);
Method method=class1.getMethod("staticShow", null);
method.invoke(null, null);
}
/**
* @throws Exception
*
*/
private static void getMethodDemo() throws Exception {
String className="cn.network.demo.Person";
Class class1=Class.forName(className);
// 反射方法 非静态,无参数的show方法
Method method=class1.getMethod("show", null);
Object object=class1.newInstance();
method.invoke(object, null);
}
}
使用URL对象
package cn.network.demo;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class URLDemo {
/**
* @param args
* 解析URL中放入数据,使用URL对象
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String str_url="http://192.168.1.136:8080/lala/hello.html?name=lili";
URL url=new URL(str_url);
System.out.println(":"+url.getProtocol());
System.out.println(":"+url.getHost());
System.out.println(":"+url.getPort());
System.out.println(":"+url.getPath());
System.out.println(":"+url.getFile());
System.out.println(":"+url.getQuery());
// 通过openconnection()获取到远程资源的连接对象
URLConnection connection=url.openConnection();
System.out.println(connection);
System.out.println("-----------------");
// 调取连接对象的读取烦烦烦,准备读取资源
InputStream in=connection.getInputStream();
byte[] buf=new byte[1024];
int len=in.read(buf);
String strs=new String(buf, 0, len);
System.out.println(strs);
}
}
反射调用
package cn.network.demo;
public interface USB{
/**
* 定义打开
*/
void open();
/**
* 定义关闭
*/
void close();
}
package cn.network.demo;
public class MouseByUSB implements USB {
@Override
public void open() {
System.out.println("mouse open");
}
/* (non-Javadoc)
* @see cn.network.demo.USB#close()
*/
@Override
public void close() {
System.out.println("mouse close");
}
}
package cn.network.demo;
public class NoteBook {
public void run() {
System.out.println("notebook run!");
}
/**
* 使用USB设备
*/
public void useUSB(USB usb) {
if(usb!=null){
usb.open();
usb.close();
}
}
}
package cn.network.demo;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class NoteBookMain {
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
NoteBook book=new NoteBook();
book.run();
book.useUSB(null);
/*
因为有了鼠标,所以需要在源程序中。创建鼠标对象并传到笔记本
希望后期出现了设备以后,可不可以不用修改NoteMain的代码,还可以不断地加入新的设备
book.useUSB(new MouseByUSB());
*/
// 对外提供配置文件
File configFile=new File("usb.properties");
if(!configFile.exists()){
configFile.createNewFile();
}
// 读取流和配置文件关联
FileInputStream inputStream=new FileInputStream(configFile);
Properties properties=new Properties();
// 将流中的数据加载到properties
properties.load(inputStream);
for (int i = 0; i < properties.size(); i++) {
String className=properties.getProperty("usb"+i);
// 对指定的类进行加载
Class class1=Class.forName(className);
USB usb=(USB) class1.newInstance();
book.useUSB(usb);
}
}
}
package cn.network.demo;
public class Person {
private String name;
public int age;
/*public Person() {
super();
System.out.println("I'm person.");
}*/
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show() {
System.out.println("Person show run!");
}
public static void staticShow() {
System.out.println("staticShow run!");
}
public static void paramShow(String name,int age) {
System.out.println("show"+name+"-----"+age);
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}