1 package cn.temptation; 2 3 import java.net.InetAddress; 4 5 public class Sample01 { 6 public static void main(String[] args) throws Exception { 7 /* 8 * OSI模型:Open System Interconnection,开放系统互联 9 * 分为七层:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 10 * 11 * TCP/IP模型: 12 * 分为四层:应用层、传输层、网际层、主机至网络层 13 * 14 * OSI模型的会话层、表示层、应用层 对应 TCP/IP模型的应用层 15 * OSI模型的传输层 对应 TCP/IP模型的传输层 16 * OSI模型的网络层 对应 TCP/IP模型的网际层 17 * OSI模型的物理层、数据链路层 对应 TCP/IP模型的主机至网络层 18 * 19 * 常用协议: 20 * 应用层:HTTP协议、HTTPS协议、FTP协议 21 * 传输层:TCP协议、UDP协议 22 * 网络层:IP协议 23 * 24 * 网络编程的三要素:地址、端口、协议 25 * 类比:人 和 人 的交流 26 * 27 * 类 InetAddress:此类表示互联网协议 (IP) 地址。 28 * 29 * InetAddress类的常用成员方法: 30 * 1、static InetAddress getByName(String host):在给定主机名的情况下确定主机的 IP 地址。 31 * 2、String getHostName():获取此IP地址的主机名。 32 * 3、String getHostAddress():返回 IP地址字符串(以文本表现形式)。 33 */ 34 35 // 命令行窗口下输出hostname,可以查看到本机的名称 36 InetAddress address = InetAddress.getByName("temptation"); 37 System.out.println(address); // temptation/192.168.137.2 38 39 String hostname = address.getHostName(); 40 System.out.println(hostname); // temptation 41 42 String ip = address.getHostAddress(); 43 System.out.println(ip); // 192.168.137.2 44 } 45 }
1 package cn.temptation; 2 3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6 import java.net.InetAddress; 7 8 public class Sample02 { 9 public static void main(String[] args) throws IOException { 10 /* 11 * 传输协议:人们为了通信而制定的规则 12 * 常用协议:UDP、TCP 13 * 14 * 套接字Socket的机制: 15 * 1、进行通信的双方都有Socket 16 * 2、网络通信实际是Socket之间的通信 17 * 3、数据在Socket之间通过IO流进行传输 18 * 19 * Java语言中对UDP协议使用Socket进行了封装,提供了DatagramPacket类 和 DatagramSocket类 20 * 21 * 类 DatagramPacket:数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。 22 * 从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。 23 * 24 * DatagramPacket类的常用构造函数: 25 * 1、DatagramPacket(byte[] buf, int length):构造 DatagramPacket,用来接收长度为 length 的数据包。 26 * 2、DatagramPacket(byte[] buf, int length, InetAddress address, int port):构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。 27 * 28 * 类 DatagramSocket:此类表示用来发送和接收数据报包的套接字。 29 * 数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。 30 * 从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。 31 * 在 DatagramSocket上总是启用 UDP 广播发送。为了接收广播包,应该将DatagramSocket绑定到通配符地址。 32 * 在某些实现中,将 DatagramSocket绑定到一个更加具体的地址时广播包也可以被接收。 33 * 34 * DatagramSocket类的常用成员方法: 35 * 1、void send(DatagramPacket p):从此套接字发送数据报包。 36 * 2、void close():关闭此数据报套接字。 37 * 38 * UDP协议的发送数据: 39 * 1、创建发送端Socket对象 40 * 2、创建数据,把数据进行打包 41 * 3、调用Socket对象的发送方法发送数据包 42 * 4、释放资源 43 */ 44 45 // 1、创建发送端Socket对象 46 DatagramSocket ds = new DatagramSocket(); 47 48 // 2、创建数据,把数据进行打包 49 // A:创建数据 50 byte[] arr = ("Hello, UDP").getBytes(); 51 // B:获取地址对象 52 InetAddress address = InetAddress.getByName("temptation"); 53 // C:打包数据 54 DatagramPacket dp = new DatagramPacket(arr, arr.length, address, 1234); 55 56 // 3、调用Socket对象的发送方法发送数据包 57 ds.send(dp); 58 59 // 4、释放资源 60 ds.close(); 61 } 62 }
1 package cn.temptation; 2 3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6 import java.net.InetAddress; 7 8 public class Sample03 { 9 public static void main(String[] args) throws IOException { 10 /* 11 * DatagramSocket类的常用构造函数: 12 * DatagramSocket(int port):创建数据报套接字并将其绑定到本地主机上的指定端口。 13 * 14 * DatagramSocket类的常用成员方法: 15 * 1、void receive(DatagramPacket p):从此套接字接收数据报包。 16 * 17 * DatagramPacket类的常用成员方法: 18 * 1、byte[] getData():返回数据缓冲区。 19 * 2、int getLength():返回将要发送或接收到的数据的长度。 20 * 3、InetAddress getAddress():返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。 21 * 22 * UDP协议的接收数据: 23 * 1、创建接收端Socket对象 24 * 2、创建一个数据包接收容器 25 * 3、调用Socket对象的接收方法进行接收 26 * 4、释放资源 27 */ 28 29 // 1、创建接收端Socket对象 30 DatagramSocket ds = new DatagramSocket(1234); 31 32 // 2、创建一个数据包接收容器 33 byte[] arr = new byte[1024]; 34 DatagramPacket dp = new DatagramPacket(arr, arr.length); 35 36 // 3、调用Socket对象的接收方法进行接收 37 ds.receive(dp); 38 39 // 获取到的数据包内容可以使用 40 byte[] temp = dp.getData(); 41 int length = dp.getLength(); 42 String result = new String(temp, 0, length); 43 InetAddress address = dp.getAddress(); 44 45 System.out.println(address.getHostAddress() + "接收到的数据为:" + result); 46 47 // 4、释放资源 48 ds.close(); 49 } 50 }
1 package cn.temptation; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.net.DatagramPacket; 7 import java.net.DatagramSocket; 8 import java.net.InetAddress; 9 10 public class Sample04 { 11 public static void main(String[] args) throws IOException { 12 // 需求:基于UDP协议,实现从键盘录入内容进行发送,如果输入886,则发送端结束输入;发送内容在接收端显示出来 13 14 // 发送端 15 16 // 创建Socket对象 17 DatagramSocket ds = new DatagramSocket(); 18 19 // 键盘输入的标准输入流进行封装 20 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 21 22 String temp = null; 23 24 while ((temp = reader.readLine()) != null) { 25 if ("886".equals(temp)) { // 终止循环 26 break; 27 } else { 28 // 创建发送数据并打包 29 byte[] arr = temp.getBytes(); 30 InetAddress address = InetAddress.getByName("temptation"); 31 DatagramPacket dp = new DatagramPacket(arr, arr.length, address, 1234); 32 33 // 发送 34 ds.send(dp); 35 } 36 } 37 38 // 释放资源 39 ds.close(); 40 } 41 }
1 package cn.temptation; 2 3 import java.io.IOException; 4 import java.net.DatagramPacket; 5 import java.net.DatagramSocket; 6 import java.net.InetAddress; 7 8 public class Sample05 { 9 public static void main(String[] args) throws IOException { 10 // 需求:基于UDP协议,实现从键盘录入内容进行发送,如果输入886,则发送端结束输入;发送内容在接收端显示出来 11 12 // 接收端 13 14 // 创建接收端的Socket对象 15 DatagramSocket ds = new DatagramSocket(1234); 16 17 // 创建一个数据包接收容器 18 byte[] arr = new byte[1024]; 19 DatagramPacket dp = new DatagramPacket(arr, arr.length); 20 21 // 接收数据 22 ds.receive(dp); 23 24 // 获取到的数据包内容可以使用 25 byte[] temp = dp.getData(); 26 int length = dp.getLength(); 27 String result = new String(temp, 0, length); 28 InetAddress address = dp.getAddress(); 29 30 System.out.println(address.getHostAddress() + "接收到的数据为:" + result); 31 32 // 释放资源 33 ds.close(); 34 } 35 }
1 package cn.temptation; 2 3 import java.io.IOException; 4 import java.io.OutputStream; 5 import java.net.InetAddress; 6 import java.net.Socket; 7 8 public class Sample06 { 9 public static void main(String[] args) throws IOException { 10 /* 11 * Java语言对TCP协议的使用封装了Socket,提供了:Socket类 和 ServerSocket类 12 * 13 * 类 Socket:实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。 14 * 套接字的实际工作由 SocketImpl 类的实例执行。 15 * 应用程序通过更改创建套接字实现的套接字工厂可以配置它自身,以创建适合本地防火墙的套接字。 16 * 17 * Socket类的常用构造函数: 18 * 1、Socket(InetAddress address, int port):创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 19 * 2、Socket(String host, int port):创建一个流套接字并将其连接到指定主机上的指定端口号。 20 * 21 * Socket类的常用成员方法: 22 * 1、OutputStream getOutputStream():返回此套接字的输出流。 23 * 2、InputStream getInputStream():返回此套接字的输入流。 24 * 3、void close():关闭此套接字。 25 * 26 * 类 ServerSocket:实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。 27 * 服务器套接字的实际工作由 SocketImpl 类的实例执行。 28 * 应用程序可以更改创建套接字实现的套接字工厂来配置它自身,从而创建适合本地防火墙的套接字。 29 * 30 * ServerSocket类的常用构造函数: 31 * 1、ServerSocket(int port):创建绑定到特定端口的服务器套接字。 32 * 33 * ServerSocket类的常用成员方法: 34 * 1、Socket accept():侦听并接受到此套接字的连接。 35 * 2、void close():关闭此套接字。 36 * 37 * TCP协议的发送数据:(客户端) 38 * 1、创建客户端的Socket对象 39 * 2、获取输出流,写出数据 40 * 3、释放资源 41 */ 42 43 // 1、创建客户端的Socket对象 44 Socket socket = new Socket(InetAddress.getByName("temptation"), 1234); 45 46 // 2、获取输出流,写出数据 47 OutputStream os = socket.getOutputStream(); 48 os.write("Hello TCP".getBytes()); 49 50 // 3、释放资源 51 socket.close(); 52 53 // 注意: 54 // TCP的客户端没有连接服务端时执行,会产生执行异常:java.net.ConnectException: Connection refused: connect 55 // UDP的发送端没有接收端时执行,不会产生执行异常 56 // 理解:TCP类似打电话(没有对应号码时提示是空号或是不存在),UDP类似广播(喊一嗓子,听见了就听见了,没听见就没听见) 57 } 58 }
1 package cn.temptation; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.net.ServerSocket; 6 import java.net.Socket; 7 8 public class Sample07 { 9 public static void main(String[] args) throws IOException { 10 /* 11 * TCP协议的接收数据:(服务端) 12 * 1、创建服务端的Socket对象 13 * 2、监听客户端的连接,返回一个对应的Socket对象 14 * 3、获取输入流 15 * 4、释放资源 16 */ 17 18 // 1、创建服务端的Socket对象 19 ServerSocket serverSocket = new ServerSocket(1234); 20 21 // 2、监听客户端的连接,返回一个对应的Socket对象 22 // 监听客户端的连接,如果没有客户端连接时,一直阻塞 23 Socket socket = serverSocket.accept(); 24 25 // 3、获取输入流 26 InputStream is = socket.getInputStream(); 27 28 byte[] arr = new byte[1024]; 29 int length = is.read(arr); 30 String result = new String(arr, 0, length); 31 32 System.out.println("接收到的内容为:" +result); 33 34 // 4、释放资源 35 socket.close(); 36 serverSocket.close(); 37 } 38 }
1 package cn.temptation; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.io.OutputStreamWriter; 8 import java.net.Socket; 9 10 public class Sample08 { 11 public static void main(String[] args) throws IOException { 12 // 需求:基于TCP协议,实现从键盘录入内容进行发送,如果输入886,则客户端结束输入;发送内容在服务端显示出来 13 14 // 客户端 15 16 // 创建客户端Socket对象 17 Socket socket = new Socket("temptation", 1234); 18 19 // 键盘录入数据 20 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 21 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 22 23 String temp = null; 24 25 while ((temp = reader.readLine()) != null) { 26 if ("886".equals(temp)) { 27 break; 28 } else { 29 writer.write(temp); 30 writer.newLine(); 31 writer.flush(); 32 } 33 } 34 35 // 释放资源 36 writer.close(); 37 reader.close(); 38 socket.close(); 39 } 40 }
1 package cn.temptation; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.net.ServerSocket; 7 import java.net.Socket; 8 9 public class Sample09 { 10 public static void main(String[] args) throws IOException { 11 // 需求:基于TCP协议,实现从键盘录入内容进行发送,如果输入886,则客户端结束输入;发送内容在服务端显示出来 12 13 // 服务端 14 15 // 创建服务端Socket对象 16 ServerSocket serverSocket = new ServerSocket(1234); 17 18 // 监听连接 19 Socket socket = serverSocket.accept(); 20 21 BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 22 23 String temp = null; 24 25 while ((temp = reader.readLine()) != null) { 26 System.out.println("接收的内容为:" + temp); 27 } 28 29 // 释放资源 30 reader.close(); 31 socket.close(); 32 serverSocket.close(); 33 } 34 }