Java基础复习十五(网络)
网络通信
三大要素
- 1.IP:可以在网络中唯一的标记一台主机 127.0.0.1(本地地址/本机地址/保留地址) java中将IP面向对象了–InetAddress
- 2.端口:用来区分一台主机上的多个服务器(不可以重复) 取值范围:(0,65535) 注意点:在通信时两边的端口号要一致
- 3.网络协议:相当于指定的一个统一的标准
七层协议
应用层:与其它计算机进行通讯的一个应用,它是对应应用程序的通信服务的。
例如,一个没有通信功能的字处理程序就不能执行通信的代码,从事字处理工作的程序员也不关心OSI的第7层。但是,如果添加了一个传输文件的选项,那么字处理器的程序员就需要实现OSI的第7层。示例:TELNET,HTTP,FTP,NFS,SMTP等。
表示层:这一层的主要功能是定义数据格式及加密。例如,FTP允许你选择以二进制或ASCII格式传输。如果选择二进制,那么发送方和接收方不改变文件的内容。如果选择ASCII格式,发送方将把文本从发送方的字符集转换成标准的ASCII后发送数据。在接收方将标准的ASCII转换成接收方计算机的字符集。示例:加密,ASCII等。
会话层:它定义了如何开始、控制和结束一个会话,包括对多个双向消息的控制和管理,以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的,在某些情况下,如果表示层收到了所有的数据,则用数据代表表示层。示例:RPC,SQL等。
传输层:这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能。
示例:TCP,UDP,SPX。
网络层:这层对端到端的包传输进行定义,它定义了能够标识所有结点的逻辑地址,还定义了路由实现的方式和学习的方式。为了适应最大传输单元长度小于包长度的传输介质,网络层还定义了如何将一个包分解成更小的包的分段方法。示例:IP,IPX等。
**数据链路层:**它定义了在单个链路上如何传输数据。这些协议与被讨论的各种介质有关。示例:ATM,FDDI等。
物理层:OSI的物理层规范是有关传输介质的特性标准,这些规范通常也参考了其他组织制定的标准。连接头、帧、帧的使用、电流、编码及光调制等都属于各种物理层规范中的内容。物理层常用多个规范完成对所有细节的定义。示例:Rj45,802.3等。
URL和URI
- URL:统一资源定位器
- URI:统一资源定位符
URL的功能:
可以通过它的方法直接获取网址的各个部分,还可以访问网络的资源。
public class Demo3 {
public static void main(String[] args) throws IOException {
URL url = new URL("https://www.bingbing.com:333/a/b?name=bing&age=18");
System.out.println(url.getProtocol());//协议
System.out.println(url.getPath());//资源路径
System.out.println(url.getHost());//主机名/域名/IP地址
System.out.println(url.getQuery());//查询条件
System.out.println(url.getPort());//端口
System.out.println(url.getDefaultPort());//默认端口 443
//System.out.println(url.getContent());//查询的内容
URL url2 = new URL("https://www.baidu.com");
//System.out.println(url2.getContent());
//URLConnection代表客户端与服务器端的通信通道,这个类的实例可以用于读取或者写入url引入的资源
URLConnection connection = url2.openConnection();
//获取内部的字节输入流
InputStream inputStream = connection.getInputStream();
//进行读写
byte[] arr = new byte[1024];
inputStream.read(arr);
System.out.println(new String(arr,"utf8"));
}
}
TCP与UDP的区别:
TCP | UDP |
---|---|
是建立在连接的基础上 | 建立在非连接的基础上 |
安全性更高 | 安全性低 |
传输速度低 | 传输速度高 |
适合传输数据量大的数据 | 数据量小的数据 |
客户端(app/浏览器)
服务器端:!=主机
端口号:同一台主机上的每一个服务器都拥有自己的端口号,取值范围(0,65535),常用的端口:80,8080
- 要保证客户端和服务器端的端口号一致
- 要保证同一台主机上的不同服务器端口号不同
模拟UDP通信
-
1.创建UDP通信的对象-socket对象:对应的类是DatagramSocket.(用于UDP数据的发送与接收)
-
2.数据的准备-封装包:DatagramPacket(数据包,包括相关的属性,数据)
-
3.发送数据,通过send方法
-
4.关闭socket对象
//客户端 public class Demo4 { public static void main(String[] args) throws IOException { //模拟UDP通信 //客户端 //* 1.创建UDP通信的对象-socket对象:对应的类是DatagramSocket.(用于UDP数据的发送与接收) DatagramSocket socket = new DatagramSocket(); // * 2.数据的准备-封装包:DatagramPacket(数据包,包括相关的属性,数据) /* 打包 * 参数一:要传输的数据 * 参数二:数据的长度 * 参数三:服务器所在主机的地址 * 参数四:服务器的端口 */ byte[] buf = "bingbing".getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 20000); //* 3.发送数据,通过send方法 socket.send(packet); //* 4.关闭socket对象 socket.close(); } }
package com.qf.test; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; /* * 作为UDP的服务器端 */ public class Demo5 { public static void main(String[] args) throws IOException { //服务器端:接收数据 /* * 1.创建socket对象,并绑定端口号---DatagramSocket * 2.创建包对象,创建空数组,准备接收传来的数据 * 3.接收数据 * 4.关闭相关的对象 */ System.out.println("启动服务器成功,可以随时接收数据"); // * 1.创建socket对象,并绑定端口号---DatagramSocket DatagramSocket socket = new DatagramSocket(20000); //* 2.创建包对象,创建空数组,准备接收传来的数据 byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); //* 3.接收数据:当服务器运行起来,让他一直处于监听状态的方法 socket.receive(packet); //显示所有数据 byte[] bytes = packet.getData(); System.out.println(new String(bytes)); //* 4.关闭相关的对象 socket.close(); } }
//* 随时发随时收–使用UDP完成
//客户端public class demo1{ public static void main(String[] args){ //1.创建UDP通信的对象-socket对象:对应的类是DatagramSocket.(用于UDP数据的发送与接收) DatagramSocket socket = new DatagramSocket(); /* 2.数据的准备-封装包:DatagramPacket(数据包,包括相关的属性,数据) /* 打包 * 参数一:要传输的数据 * 参数二:数据的长度 * 参数三:服务器所在主机的地址 * 参数四:服务器的端口 */ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); String data = null; while((data = bufferedReader.readLine())!=null){ DatagramPacket packet = new DatagramPacket(data.getbytes(),data.length,InetAddress.getLocalHost(),2000); //* 3.发送数据,通过send方法 socket.send(packet); //当输入over的时候结束 if (data.equals("over")) { break; } } //* 4.关闭socket对象 socket.close(); } }
/* * 服务器端 */ public class Demo7 { public static void main(String[] args) throws IOException { System.out.println("启动服务器成功,可以随时接收数据"); // * 1.创建socket对象,并绑定端口号---DatagramSocket DatagramSocket socket = new DatagramSocket(20000); //不断的接收数据 while (true) { //* 2.创建包对象,创建空数组,准备接收传来的数据 byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); //* 3.接收数据:当服务器运行起来,让他一直处于监听状态的方法 socket.receive(packet); //显示所有数据 byte[] bytes = packet.getData(); String data = new String(bytes); System.out.println(new String(bytes)); //当输入over的时候结束 if (data.trim().equals("over")) { break; } } //* 4.关闭相关的对象 //socket.close(); } }
模拟TCP通信
-
在客户端与服务器端通信的时候,对于客户端既要进行输入又要进行输出,所以在Socket对象的内部就内置了输入流和输出流,
-
当进行数据传输的时候,将数据放入socket对象的内部,将socket对象传到服务器端,相当于在客户端与服务器端建立了一个通道,
-
两端使用同一个socket对象.
-
package test; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; /* 客户端 */ public class demo4 { public static void main(String[] args) throws IOException { //1.创建Socket对象并绑定端口,管理服务器主机 Socket socket = new Socket(InetAddress.getLocalHost(),30000); //2.准备数据 String data = "BigData1923,你好"; //3.调用Socket内部的输出流向网络写数据 OutputStream outputStream = socket.getOutputStream(); outputStream.write(data.getBytes()); //4.使用socket的输入流将服务器回传的信息打印 InputStream inputStream =socket.getInputStream(); //将内容打印到控制台 byte[] arr = new byte[100]; int num = inputStream.read(arr); String data1 = new String(arr,0,num); System.out.println(data1); socket.close(); } }
package test; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /* 服务器端 */ public class demo5 { public static void main(String[] args) throws IOException { //1.创建ServerSocket对象并设置端口 ServerSocket serverSocket = new ServerSocket(30000); //2.接收从客户端传来的socket对象 Socket socket = serverSocket.accept(); //3.使用socket的输入流卸货 InputStream inputStream = socket.getInputStream(); //将内容打印到控制台 byte[] arr = new byte[100]; int num = inputStream.read(arr); String data = new String(arr,0,num); System.out.println(data); //给客户端回发一个信息,告知接收成功 //获取socket的输出流 OutputStream outputStream = socket.getOutputStream(); outputStream.write("你好,BigData1923".getBytes()); //4.关闭资源 serverSocket.close(); } }