一、网络模型概述
OSI(Open SystemInterconnection 开放系统互联)参考模型:
7层应用层:一些应用软件(终端的应用)
6层表示层:对接收的数据进行解释、加密与解密、压缩与解压缩
5层会话层:通过传输层建立数据传输的通路。主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名)。
4层传输层:传输协议和端口号(按照什么样的方式把数据发出去,发到哪去),这一层数据叫做 段;
3层网络层:将从下层接收到的数据进行 IP 地址的封装(IP:Internet协议),决定数据发向哪一台主机。工作设备:路由器(数据包方向的定义),这一层数据叫做数据包;
2层数据链路层:从物理层接收数据进行MAC地址(网卡的地址),这一层数据叫做 帧,这一层工作设备是交换机。
1层物理层(最底层):物理设备,比如:网线、无线等各种传输介质;它的主要作用是传输比特流,这一层数据叫做 比特。
TCP/TP参考模型:
应用层:
传输层:
网际层:
主机至网络层:
二、网络要素-IP地址、端口和传输协议
网络通讯要素:
1、IP地址(4段数字,每段是一个字节,最大255,如:192.168.1.1)
网络中设备的标识;
不易记忆,可用主机名;
本地回环地址:127.0.0.1 主机名:localhost 《只可以访问本机》
2、端口号:
<1>用于标识进程的逻辑地址;
<2>有效端口:0~65535,其中0~1024系统使用或保留端口(不能使用,会和windows冲突)
防火墙可以禁用端口
3、传输协议:“传输的规则”
传输层中,常见协议:TCP,UDP
UDP:数据及源和目的封装成数据包,不需要建立连接,地址对不对不重要
数据包大小限制在64k,大数据可以拆成多个包,一个个传输(所以,可以传输大数据);
因无连接,是不可靠协议;
不需要建立连接,速度快;
(QQ聊天、视频通话,对讲机)
TCP(传输控制协议):
建立连接,形成传输数据的通道;
在连接中进行大数据量传输;
通过三次握手完成连接,是可靠协议;
必须建立连接,效率会稍低。
(打电话、下载数据)
三、IP地址
1、java.net包->InetAddress类(查JDK API帮助文档):此类表示互联网协议(IP)地址
存在网际层;该类不能直接使用,需要用方法来返回。
演示:src->new class ->Package:cn.itcast.net.p1.ip-> IPDemo
Demo:1 package cn.itcast.net.p1.ip;
2 import java.net.InetAdddress ;
3 import java.net.UnknownHostException;
4 public class IPDemo{
5 public static void main( String[] args)throws UnKnownHostException{
6 //获取本地主机ip地址对象。
7 InetAddress ip =InetAddress.getLocalHost();
8//获取其他主机的ip地址对象
9 ip= InetAddress.getByName(“192.168.1.100”);//InetAddress.getByName(“my_think”);
10 System.out.println(ip.getHostAddress());
11System.out.println(ip.getHostName());
}
}
注:获取其他主机的ip地址对象,如:获取百度贴吧ip地址:ip = InetAddress.getByName(“tieba.baidu.com”);由于需要解析,所以会很慢。
2、getAllByName(String host) 方法:有的主机对应的ip地址不唯一
四、域名解析
主机名
域名
商业化组织
所属国家类别
DNS:域名解析服务
屏蔽恶意网站方法:
C盘->windows->system32(system64)->drivers->etc->hosts文件,用EditPlus打开,把恶意网站的网址写到本机ip地址:
127.0.0.1 flydown.net
屏蔽成功!!!
360阻拦就是这么做的!!!!
五、UDP协议--发送端
1、 Socket:
即通信的两端,数据在Socket之间进行传输,它是网络服务提供的一种机制。
(网络编程又称为Socket编程)
2、 UDP传输:
Java包:
UDP传输协议对应的端点服务对象:DatagramSocket类,此类表示用来发送和接收数据报包的套接字。(类似对讲机),数据报包用来实现无连接包投递服务,每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。不对包投递作出保证。(不可靠)
有的包用来接收,有的包用来封装发送数据,最大的不同是对于用来存储发送类的数据包都有一个明确的信息叫做 目的地址,凡是有IP对象的都是发送
3、 示例程序
创建UDP传输的发送端。
思路:
1. 建立udp的socket服务
2. 将要发送的数据封装到数据包中
3. 通过udp的socket服务将数据包发送出去。
4. 关闭socket服务
1,udpsocket服务。使用DatagramSocket对象
2,将要发送的数据封装到数据包中
使用DatagramPacket将数据封装到该对象包中
3,通过udp的socket服务将数据包发送出去,使用send方法。
4,关闭资源
代码:
package cn.itcast.net.p2.udp; import java.io.IOException; import java.net.*; import static java.net.InetAddress.getByName; /** * Created by Administrator on 2017/4/24 0024. */ public class UDPSendDemo { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(); String str = "udp传输演示:哥们来了!"; byte[] buf = str.getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length, InetAddress.getByName("192.168.1.108"),10000); ds.send(dp); ds.close(); } }
六、UDP协议--接收端
建立UDP接收端的思路:
1、建立udp socket服务,因为是要接收数据,必须要明确一个端口号
2、创建数据包,用于存储接收到的数据,方便用数据包对象的方法解析这些数据
3、使用socket 服务的receive方法将接收的数据存储到数据包中
4、通过数据包的方法解析数据包中的数据
5、关闭资源
a) 建立udp socket 服务
b) 创建数据包
c) 使用接收方法将数据存储到数据包中
d) 通过数据包对象的方法,解析其中的数据,比如,地址,端口,数据内容。
e) 关闭资源
UDP发送端code:
package cn.itcast.net.p2.udp; import java.io.IOException; import java.net.*; /** * Created by Administrator on 2017/4/24 0024. */ public class UDPSendDemo { public static void main(String[] args) throws IOException { System.out.println("发送端启动......"); DatagramSocket ds = new DatagramSocket(); String str = "udp传输演示:哥们来了!"; byte[] buf = str.getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length, InetAddress.getByName("192.168.1.108"), 10000); ds.send(dp); ds.close(); } }
UDP接收端code:
package cn.itcast.net.p2.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * Created by Administrator on 2017/4/24 0024. */ public class UDPReceDemo { public static void main(String[] args) throws IOException { System.out.println("接收端启动......"); DatagramSocket ds = new DatagramSocket(10000); byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); ds.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); ds.close(); } }
七、UDP协议--聊天程序
192.168.1.108中
192 168 1这些位都是网络位,叫做 192.168.1 网络 108 被称为IP地址位;
IP地址位:0~255 0 不能用 ,因为0 代表网络位-->192.168.1.0网段
IP地址有效位 0 ~254 255不是IP地址,属于广播地址,如果把信息发到192.168.1.255意味着,把信息发送到所有192.168.1的所有网段里面存活的机子上,因此直接发广播可以实现多人聊天。
Code:两个接口,一个main方法如下
Send接口:
package cn.itcast.net.p3.chat; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * Created by Administrator on 2017/4/24 0024. */ public class Send implements Runnable { private DatagramSocket ds; public Send(DatagramSocket ds){ this.ds = ds; } public void run(){ try{ BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String Line = null; while((Line = bufr.readLine())!=null) { byte[] buf = Line.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.255"), 10000); ds.send(dp); if("886".equals(Line)) break; } ds.close(); } catch (IOException e) { e.printStackTrace(); } } }
Rece接口:
package cn.itcast.net.p3.chat; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * Created by Administrator on 2017/4/24 0024. */ public class Rece implements Runnable{ private DatagramSocket ds; public Rece(DatagramSocket ds){ this.ds = ds; } public void run() { try { while (true) { byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String text = new String(dp.getData(), 0, dp.getLength()); System.out.println(ip + "::" + text); if(text.equals("886")){ System.out.println(ip+"...is leaving"); } } }catch(IOException e){ e.printStackTrace(); } } }
ChatDemo:
package cn.itcast.net.p3.chat; import java.io.IOException; import java.net.DatagramSocket; /** * Created by Administrator on 2017/4/24 0024. */ public class ChatDemo { public static void main(String[] args) throws IOException { DatagramSocket send = new DatagramSocket(); DatagramSocket rece = new DatagramSocket(10000); new Thread(new Send(send)).start(); new Thread(new Rece(rece)).start(); } }
八、TCP协议--客户端
TCP涉及两个对象:
1、Socket:此类实现客户端套接字(也可称为“套接字”)。套接字是两台机器间通信的端点。
构造方法:
Socket():通过系统默认类型的SocketImpl创建未连接套接字;
connect(SocketAddressendpoint):将此套接字连接到服务器。
Socket(InetAddress address, intport):创建一个流套接字并将其连接到指定IP地址的指定端口号;
Socket(String host, int port):(此方法比较简单)
创建一个流套接字并将其连接到指定主机上的指定端口号;
2、ServerSocket:此类实现服务器套接字。
3、客户端发数据到服务端
Tcp传输,客户端建立的过程。
1.创建tcp客户端socket服务,使用的是Socket对象,建议该对象一创建就明确目的地。要连接的主机。
2. 如果连接建立成功,说明数据传输通道已建立。该通道就是socket流,是底层建立好的。既然是流,说明这里既有输入,又有输出。想要输入或者输出流对象,可以找Socket来获取。
可以通过getOutputStream(),和getInputStream()来获取两个字节流。
3. 使用输出流,将数据写出。(写网络中)
4.关闭资源。
客户端code:(服务端,客户端程序运行时先启动服务端)
package cn.itcast.net.p4.tcp; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; /** * Created by Administrator on 2017/4/24 0024. */ public class ClientDemo { public static void main(String [] args) throws IOException { //创建客户端socket服务 Socket socket = new Socket("192.168.1.108",10004); //获取socket流中的输出流。 OutputStream out = socket.getOutputStream(); //使用输出流将指定的数据写出去 out.write("tcp演示:哥们又来了!".getBytes()); //关闭资源 socket.close(); } }
九、TCP协议--服务端
服务端接收客户端发送过来的数据,并打印在控制台上
建立tcp服务端思路:
1. 创建服务端socket服务,通过ServerSocket对象。
2. 服务端必须对外提供端口,否则客户端无法连接。
3. 获取连接过来的客户端对象
4. 通过客户端对象获取socket流读取客户端发来的数据并打印在控制台上。
5. 关闭资源。关客户端,关服务端。
服务端code:(服务端,客户端程序运行时先启动服务端)
package cn.itcast.net.p4.tcp; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /** * Created by Administrator on 2017/4/24 0024. */ public class ServerDemo { public static void main(String[] args) throws IOException { //1.创建服务端对象 ServerSocket ss = new ServerSocket(10004); //2.获取连接过来的客户端对象 Socket s = ss.accept();//阻塞式 String ip = s.getInetAddress().getHostAddress(); //3.通过socket对象获取输入流,要读取客户端发来的数据 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String text = new String(buf,0,len); System.out.println(ip+"server:"+text); s.close(); ss.close(); } }
十、TCP协议--客户端服务端交互
ClientDemo2.java:
package cn.itcast.net.p4.tcp; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /** * Created by Administrator on 2017/4/24 0024. */ public class ClientDemo2 { public static void main(String [] args) throws IOException { //创建客户端socket服务 Socket socket = new Socket("192.168.1.108",10004); //获取socket流中的输出流。 OutputStream out = socket.getOutputStream(); //使用输出流将指定的数据写出去 out.write("tcp演示:哥们又来了!".getBytes()); //读取服务端返回的数据,使用socket读取流. InputStream in = socket.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String text = new String(buf,0,len); System.out.println(text); //关闭资源 socket.close(); } }
ServerDemo.java:
package cn.itcast.net.p4.tcp; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * Created by Administrator on 2017/4/24 0024. */ public class ServerDemo2 { public static void main(String[] args) throws IOException { //1.创建服务端对象 ServerSocket ss = new ServerSocket(10004); //2.获取连接过来的客户端对象 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); //3.通过socket对象获取输入流,要读取客户端发来的数据 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String text = new String(buf,0,len); System.out.println(ip+":"+text); //使用客户端socket对象的输出流给客户端返回数据 OutputStream out = s.getOutputStream(); out.write("收到".getBytes()); s.close(); ss.close(); } }
十一、TCP协议-练习-文本转换客户端
建cn.itcast.net.p5.tcptest包à建class TextTransTest
客户端输入字母数据,发送给服务端,服务端收到后显示在控制台,并将该数据转成大写返回给客户端,直到客户端输入over,转换结束。
创建一个英文大写转换服务器。
分析:
有客户端和服务端,使用tcp传输
à建两个class:TransServer和TransClient
TransClient.Java
思路:
客户端:
1. 需要先有socket端点
2. 客户端的数据源:键盘
3. 客户端的目的:socket。
4. 接收服务端的数据,源:socket
5. 将数据显示打印出来:目的:控制台
6. 在这些流中操作的数据,都是文本数据。
转换客户端:
1. 创建socket客户端对象
2. 获取键盘录入
3. 将录入的信息发送给socket输出流
//1、创建socket客户端对象
Sockets = new Socket(“192.168.1.108”,1004);
//2、获取键盘录入
BufferedReaderbufr = new BufferedReader(new InputStreamReader(System.in));
//socket输出流
//new BufferedWriter(new//OutputStreamWriter(s.getOutputStream()));
PrintWriter out = newPrintWriter(s.getOutputStream(),true);
//4、socket 输入流,读取服务端返回的大写数据
BufferedReader burIn = newBufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
While((line=bufr.readLine())!=null){
if(“over”.equals(line))
break;
out.println(line);
//读取服务端发回的一行大写数据
String upperStr =burIn.readLine();
System.out.println(upperStr);
}
s.close();
TransServer.Java
转换服务端
分析:
1. Serversocket服务
2. 获取socket对象
3. 源:socket,读取客户端发过来的需要转换的数据
4. 目的:显示在控制台上。
5. 将数据转成大写发给客户端。
//1、
Server Socketss = new ServerSocket(1004);
//2、获取socket对象
Socket s = ss.accept();
//获取ip
String ip =s.getInetAddress().getHostAddress();
System.out.println(ip+“……connected”);
//3、获取socket读取流,并装饰
BufferedReader bufIn = newBufferedReader(new BufferedReader(new InputStreamReads(s.getInputStream())));
//4、获取输出流,并装饰
PrintWriter out = newPrintWriter(s.getOutputStream(),true);
String line =null;
while((line = bufIn.readLine())!=null){
System.out.println(line);
out.println(line.toUpperCase());
}
s.close();
ss.close();
十二、TCP协议-练习-常见问题
常见错误:
1、缺少结束标记
2、因为阻塞式方法造成双方都在等待的情况
客户端输入over,服务端结束原因:TransClient.Java中的s.close()导致的;
服务端去掉刷新,输出去掉ln,客户端也去掉刷新,输出去掉ln,会导致客户端连接不到服务器,原因:
客户端通过键盘录入读到数据,没有发给服务端,输出流都传到PrintWriter中去了,并没有刷新到socket流中去
解决方法:
在客户端while循环中加入:out.flush();//刷新一次 可以保证客户端联入服务器,但是并没有转换成大写,原因:服务端读到数据了,但是没读完,客户端确定读完的标记是换行符。解决:在客户端while循环中—>out.print(line+”\r\n”);结果服务端读到数据,但是客户端没有转换成大写,解决:服务端while循环中—>out.print(line.toUpperCase()+”\r\n”);
out.flush();
为了方便都采用上一节代码表示!!!!
十三、TCP协议-练习-上传文本文件
上传文本文件
1、转换客户端中把键盘录入改为读取一个文本文件,服务端不是把数据打印到后台,而是存在一个文档中,这就是上传。
2、上传文本文件,用到字符流
3、建包cn.itcast.net.p6.upload.textà建UploadClient.java和UploadServer.java
UploadClient.java
package cn.itcast.net.p6.upload.text; import java.io.*; import java.net.Socket; /** * Created by Administrator on 2017/4/26 0026. */ public class UploadClient { public static void main(String[] args) throws IOException { Socket s = new Socket("192.168.1.108",10000); //在e盘新建一个client.txt文本文档 File file = new File("c:\\client.txt"); System.out.println(file.exists()); BufferedReader bufr = new BufferedReader(new FileReader(file)); PrintWriter out = new PrintWriter(s.getOutputStream(),true); String line = null; while((line = bufr.readLine())!=null){ out.println(line); } //告诉服务端,客户端写完了 s.shutdownOutput(); //out.println("over"); //读取socket流 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String str = bufIn.readLine(); System.out.println(str); bufr.close(); s.close(); } }
UploadServer.java
package cn.itcast.net.p6.upload.text; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * Created by Administrator on 2017/4/26 0026. */ public class UploadServer { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10000); Socket s = ss.accept(); System.out.println(s.getInetAddress().getHostAddress()+"......connected"); //读取客户端发过来的数据 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); //目的:写到服务端文档 BufferedWriter bufw = new BufferedWriter(new FileWriter("c:\\server.txt")); String line = null; while((line=bufIn.readLine())!=null){ //if("over".equals(line)) // break; bufw.write(line); bufw.newLine(); bufw.flush(); } PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("上传成功"); bufw.close(); s.close(); ss.close(); } }
十四、TCP协议-上传图片客户端和服务端
1、建包cn.itcast.net.p1.uploadpic
2、建classUploadPicClient.java和 UploadPicServer.java
3、UploadPicClient.java代码:
package cn.itcast.net.p1.uploadpic; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /** * Created by Administrator on 2017/4/26 0026. */ public class UploadPicClient { public static void main(String[] args) throws IOException { //1、创建客户端socket Socket s = new Socket("192.168.1.108",10000); //2.读取客户端要上传的图片文件 FileInputStream fis = new FileInputStream("d:\\Pic.JPG"); //3、获取socket输出流,将读到图片数据发送给服务端。 OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1){ out.write(buf,0,len); } //4、告诉服务端说:这边的数据发送完毕。让服务端停止读取。 s.shutdownOutput(); //读取服务端发回的内容 InputStream in = s.getInputStream(); byte[] bufIn = new byte[1024]; int lenIn = in.read(buf); String text = new String(buf,0,lenIn); System.out.println(text); fis.close(); s.close(); } }
4、UploadPicServer.java代码:
package cn.itcast.net.p1.uploadpic; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * Created by Administrator on 2017/4/26 0026. */ public class UploadPicServer { public static void main(String[] args) throws IOException { //创建tcp的socket服务端 ServerSocket ss = new ServerSocket(10000); //获取客户端 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); //读取客户端发来的数据 InputStream in = s.getInputStream(); //将读取到数据存储到一个文件中 File dir = new File("c:\\pic"); if(!dir.exists()) dir.mkdirs(); File file = new File(dir,ip+".JPG"); FileOutputStream fos = new FileOutputStream(file); byte[] buf = new byte[1024]; int len = 0; while((len=in.read(buf))!=-1){ fos.write(buf,0,len); } //获取socket输出流,将上传成功字样发给客户端 OutputStream out = s.getOutputStream(); out.write("上传成功".getBytes()); fos.close(); s.close(); ss.close(); } }
1、服务器原理:
把连接过来的客户端封装到一个线程中去
2、Web server:
能提供web 资源访问的服务机器
3、
3、UploadPicServer.java:
package cn.itcast.net.p1.uploadpic; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * Created by Administrator on 2017/4/26 0026. */ public class UploadPicServer { public static void main(String[] args) throws IOException { //创建tcp的socket服务端 ServerSocket ss = new ServerSocket(10000); while(true){ Socket s = ss.accept(); new Thread(new UploadTask(s)).start(); } //ss.close(); } }
UploadTask.java:
package cn.itcast.net.p1.uploadpic; import java.io.*; import java.net.Socket; /** * Created by Administrator on 2017/4/26 0026. */ public class UploadTask implements Runnable{ private Socket s; UploadTask(Socket s){ this.s = s; } public void run() { //获取客户端 int count = 0; String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + ".....connected"); //读取客户端发来的数据 try { InputStream in = s.getInputStream(); //将读取到数据存储到一个文件中 File dir = new File("c:\\pic"); if (!dir.exists()) dir.mkdirs(); File file = new File(dir, ip + ".JPG"); //如果文件已经存在于服务端 while(file.exists()){ file = new File(dir,ip+"("+(++count)+").JPG"); } FileOutputStream fos = new FileOutputStream(file); byte[] buf = new byte[1024]; int len = 0; while ((len = in.read(buf)) != -1) { fos.write(buf, 0, len); } //获取socket输出流,将上传成功字样发给客户端 OutputStream out = s.getOutputStream(); out.write("上传成功".getBytes()); fos.close(); s.close(); }catch(IOException e){ } } }
UploadPicClient.java:
package cn.itcast.net.p1.uploadpic; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; /** * Created by Administrator on 2017/4/26 0026. */ public class UploadPicClient { public static void main(String[] args) throws IOException { //1、创建客户端socket Socket s = new Socket("192.168.1.108",10000); //2.读取客户端要上传的图片文件 FileInputStream fis = new FileInputStream("d:\\Pic.JPG"); //3、获取socket输出流,将读到图片数据发送给服务端。 OutputStream out = s.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1){ out.write(buf,0,len); } //4、告诉服务端说:这边的数据发送完毕。让服务端停止读取。 s.shutdownOutput(); //读取服务端发回的内容 InputStream in = s.getInputStream(); byte[] bufIn = new byte[1024]; int lenIn = in.read(buf); String text = new String(buf,0,lenIn); System.out.println(text); fis.close(); s.close(); } }
十六、常见客户端和服务端
最常见客户端:
浏览器:IE
最常见的服务端:
服务器:Tomcat
十七、了解客户端和服务器端原理
为了了解其原理:
1,自定义服务端,使用已有的客户端IE,了解一下客户端给服务器端发了什么请求?
package cn.itcast.net.p2.ie_server; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * Created by Administrator on 2017/4/26 0026. */ public class MyTomcat { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(9090); Socket s = ss.accept(); System.out.println(s.getInetAddress().getHostAddress()+".....connected"); InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String text = new String(buf,0,len); System.out.println(text); //给客户端一个反馈信息 PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("<font color='red' size='7'>欢迎光临</font>"); s.close(); ss.close(); } }
在浏览器上输入 http://localhost:9090/
运行结果:发送的请求是:
0:0:0:0:0:0:0:1.....connected
GET/ HTTP/1.1 请求行 请求方式/myweb/1.html 请求的资源路径 http协议版本。
Host:localhost:9090
Connection:keep-alive
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8请求消息头 属性名:属性值
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/50.0.2661.102 Safari/537.36
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8
//请求头和请求体之间有一个空行
//请求体。
十八、模拟一个浏览器获取信息
package cn.itcast.net.p2.ie_server; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.Socket; /** * Created by Administrator on 2017/4/27 0027. */ public class MyBrowser { public static void main(String[] args) throws IOException { Socket s = new Socket("192.168.1.108",8080); //模拟浏览器,给tomcat服务端发送符合http协议的请求消息。 PrintWriter out = new PrintWriter(s.getOutputStream(),true); out.println("GET /myweb/1.html HTTP/1.1"); out.println("Accept: */*"); out.println("Host: 192.168.1.108:8080"); out.println("Connection:close"); out.println(); out.println(); InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String str = new String(buf,0,len); System.out.println(str); s.close(); } }
打开Tomcat服务器(自己写的页面在D:\apache-tomcat-8.5.12\webapps\myweb)
运行后IDEA显示:
//服务端发回的应答消息
HTTP/1.1200 OK//应答行,http的协议版本 应答状态码 应答状态描述信息(OK我没有显示)// HTTP/1.1404 not found
应答消息属性信息。属性名:属性值
Accept-Ranges:bytes
ETag:W/"107-1493263474134"
Last-Modified:Thu, 27 Apr 2017 03:24:34 GMT//数据最后修改的时间
Content-Type:text/html
Content-Length:107
Date:Thu, 27 Apr 2017 03:25:47 GMT
Connection:close
//空行
//应答体
<html>
<head>
<title>这是我的网页</title>
</head>
<body>
<h1>欢迎光临</h1>
</body>
</html>
十九、URL&URLConnection
Java.net类URL
1、代表一个统一资源定位符。
2、定位:根据符号:http://192.168.1.108:8080/myweb/1.html能定位到网络上的一个资源
3、 URI是统一资源标识符,每个URL都是URI,但不一定每一个URI都是URL;
因为URI还包括子类,即统一资源名称(URN),它命名资源但不指定如何定位资源。
4、URL对象可以直接解析URL地址
5、URLDemo.Java:
package cn.itcast.net.p2.ie_server; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; /** * Created by Administrator on 2017/4/30 0030. */ public class URLDemo { public static void main(String[] args) throws IOException { String str_url = "http://192.168.17.1:8080/myweb/1.html?name=lisi"; URL url = new URL(str_url); System.out.println("getProtocol:"+url.getProtocol()); System.out.println("getHost:"+url.getHost()); System.out.println("getPort:"+url.getPort()); System.out.println("getFile:"+url.getFile()); System.out.println("getPath:"+url.getPath()); System.out.println("getQuery:"+url.getQuery()); //InputStream in = url.openStream(); //获取url对象的Url连接器对象,将连接封装成了对象:java中内置的可以解析的具体协议的对象+socket URLConnection conn = url.openConnection(); System.out.println(conn); String value = conn.getHeaderField("Content-Type"); System.out.println(value); //sun.net.www.protocol.http.HttpURLConnection:http://192.168.17.1:8080/myweb/1.html?name=lisi InputStream in = conn.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String text = new String(buf,0,len); System.out.println(text); in.close(); } }
二十、常见网络结构
网络结构:
1、C/S client/server
特点:
该结构的软件,客户端和服务端都需要缩写。
开发成本较高,维护较为麻烦。
好处:
客户端在本地可以分担一部分运算。
2、B/S browser/server
特点:
该结构的软件,只开发服务器端,不开发客户端,因为客户端直接由浏览器取代。
开发成本相对低,维护更为简单。
缺点:
所有运算都要在服务端完成