一、计算机网络基础
1、计算机网络定义
把分布在不同区域的计算机与专门的外部设备通过通信线路连接成复杂的网络系统, 众多计算机之间可以方便的互相传输信息,数据共享。
2、计算机网络主要功能:
资源共享
信息传输与集中处理
均衡负荷与分布处理
综合信息服务
计算机之间需要数据传输,离不开网络通信协议,网络通信协议就是 双方在传输数据时的约定
3、网络通信协议定义:
计算机在数据传输时的通用标准 。约定了他们的传输速率,传输代码、代码结构,出错控制等标准。
根据国际约束的协议分为网络通信协议的七层协议,按照实际应用也可分为四层协议
七层从下往上 : 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
四层协议从下往上: 物理+数据链路层 、网络层(IP层)、传输层、应用层
由于网络传输本身是比较复杂的过程,Java 对每一层进行封装,对每一层提供对应的API ,使我们在进行网络传输时不需要跟踪底层协议,只需对每一层提供的API掌握,同时数据传输的过程和 文件流一样操作,从而简化该过程。 所以网络传输会使用流、多线程的概念。
二、Java的网络编程
Java的网络编程包 java.net.*
网络层: 掌握网络IP 和 端口号 java.net.InetAddress \Inet4Address\Inet6Address
IP的定义: IP(Internet Protocol) 互联网协议, 在全球互联网范围内每一个IP地址表示一台独立的计算机(广域网内) ,IPv4由四个段组成,每一个段的数都从0-255
通过一个IP地址可以路由到唯一的计算机。
端口号(PORT): 一台计算机上可运行多个应用程序,通过端口号区分该计算机的指定应用程序, 同一个计算机下,不同应用程序,端口号一定不同。 端口号的范围(0-65535)
常用端口号 :
端口号 | 对应服务 | 端口号 | 对应服务 |
---|---|---|---|
7 | Echo服务器 | 80(http)/443(https) | 浏览器默认端口 |
21 | ftp | 8080 | Tomcat默认端口 |
23 | telnet远程连接 | 3306 | MySql |
25 | SMTP(邮件服务) | 110 | POP3 |
2425 | 内网通端口/飞秋 | 1521 | Oracle |
每一个通信程序都有一个端口号
IP层的类:
java.net. InetAddress
常用方法
getLocalHost() : 获取本地IP对象
getHostAddress():获取IP地址
getHostName():获取计算机名
getAddress():获取ip地址的数组表现形式
static getByName(参数) :通过ip地址或计算机名 返回一个InetAddress对象
//确定主机名称的IP地址。
// 获取本机 LocalHost 表示本机ip
InetAddress inet = InetAddress.getLocalHost();
System.out.println("主机地址:"+inet.getHostAddress());
System.out.println("主机名:"+inet.getHostName());
System.out.println("主机名IP数组:"+
Arrays.toString( inet.getAddress()));
// 也可以通过ip地址获取InetAddress对象
InetAddress inet2= InetAddress.getByName("DESKTOP-346CK63");
//获取ip地址
System.out.println(inet2.getHostAddress());
InetAddress inet3 = InetAddress.getByName("192.168.7.189");
//获取计算机名
System.out.println(inet3.getHostName());
InetAddress inet4 = InetAddress.getByName("192.168.7.103");
System.out.println("对方的计算机名:"+ inet4.getHostName());
URL类:
URL全称 统一资源定位符,用于访问互联网上的资源地址,也称为 网址,
完成的URL地址包括以下部分
协议名://ip地址:端口号/文件路径/文件名
例如: http://47.100.182.246:8080/robot/
协议名: http 、https、ftp协议
URL : url的路由对象
URLConnection : url的连接对象, 可获取输入流
常用方法:
getConnect() : 获取连接对象的内容
-
getConnectTimeout()
URL url = new URL("https://www.baidu.com/");
// 获取根据ip + 端口 + 协议 + 文件组成URL
// URL url2 = new URL("http","47.100.182.246",8080,"/robot");
//获取连接 (与该地址的连接)
URLConnection conn = url.openConnection();
// 获取这里的资源,首先需要获取输入流 ,下载远程资源相当于IO流操作
InputStream is = conn.getInputStream();
// 包装成一个字符流
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String str=null;
while((str =br.readLine()) !=null){
System.out.println(str);
}
br.close();
下载文件 案例
public static void main(String[] args) throws IOException {
//https://zhuanlan.zhihu.com/p/285529011
// 1、创建连接
URL url = new URL("https://zhuanlan.zhihu.com/p/285529011");
System.out.println(url);
// 2、打开连接
InputStream is = url.openStream();
// 定义文件输出流
FileOutputStream fos = new FileOutputStream("d:/zhihu.html");
byte [] b = new byte[1024];
int len = 0;
while( (len =is.read(b)) !=-1){
fos.write(b,0,len);
}
System.out.println("文件下载 成功");
fos.close();
is.close();
}
传输层(TCP/UDP)
传输层用于数据的传输,在数据传输过程中根据数据的可靠性可分为两类,
1、基于TCP的传输
TCP特点: 两台计算机之间建立可靠连接,基于Socket的通道一旦建立,则数据可通过字节流的方式传输到另一方, 安全的可靠协议 ,
2、基于UDP的传输
UDP特点: 它面向无连接的协议,不保证数据的可靠性,传播速度比较快
TCP和UDP的区别
TCP协议 | UDP协议 | |
---|---|---|
是否面向连接 | 面向连接 | 面向无连接 |
可靠性 | 可靠 | 不可靠 |
应用场合 | 适用于数据量较大的文件 | 数据量较少 |
速度 | 较慢 | 较快 |
在Java中如何实现TCP传输
核心类: java.net.ServerSocket : 用于接收数据的套接字
java.net.Socket :用于发送数据的套接字
套接字是两台计算机建立通信连接的端点 ,在Java对应Socket类
a、实现数据的单行发送和接收
以“客户端”发送数据给“服务端” : 客户端是发送方, 服务端是接收方
//定义数据的接收方
ServerSocket server = new ServerSocket(8888);
// 监听返回套接字的 对象 线程会阻塞在这里,只要有人发送消息,就获取消息对应的端点Socket
Socket socket = server.accept();
System.out.println(socket.getInetAddress().getHostAddress()+"发送了消息");
// 获取接收对象的输入流
InputStream is = socket.getInputStream();
byte [] b = new byte[100];
// 实际读取的长度
int len = is.read(b);
String result = new String(b,0,len);
System.out.println(
socket.getInetAddress().getHostAddress()+"发送的数据:"+result);
public static void main(String[] args) throws IOException {
// 客户端用于发送数据
//创建Socket对象 并根据ip地址和端口号8888
Socket socket = new Socket(InetAddress.getByName("192.168.7.189"),8888);
System.out.println("请输入你要发送的内容:");
Scanner sc = new Scanner(System.in);
String msg = sc.next();
OutputStream os = socket.getOutputStream();
os.write(msg.getBytes());
System.out.println("发送成功。");
}
一、UDP通信
UDP是面向无连接的通信协议, 它负责将数据打包后传输,数据以数据报文的形式存在DatagramPacket中, 不能确保对方是否一定能收到,它发送的速度较快。
java支持UDP编程的核心类
1、java.net.DatagramSocket类 :用于发送和接收包裹
2、java.net.DatagramPacket类: 存取数据包裹
1、点对点单次发送接收
发送方:
接收方:
public static void main(String[] args) throws IOException {
// 定义接收方
// 1 、创建接收数据对象
DatagramSocket ds = new DatagramSocket(8882);
byte [] b = new byte[1024];
// 2、创建用于接收的数据包对象
DatagramPacket dp = new DatagramPacket(b ,b.length);
// 3、接收数据报包
ds.receive(dp);
// 4、接收后数据存放在b数组中 ,转成字符串 ,以接收的实际长度转成字符串
String msg = new String(b,0,dp.getLength());
System.out.println("接收来自【"+dp.getAddress().getHostAddress()
+"】的数据:"+msg);
//5、关闭
ds.close();
}
}
2、点对点 一个来回的接收和发送
public static void main(String[] args) throws IOException {
// 1、先发送
DatagramSocket ds = new DatagramSocket();
System.out.println("请输入你要发送的数据 ");
Scanner sc = new Scanner(System.in);
String info= sc.nextLine();
// 将数据打包
DatagramPacket dp = new DatagramPacket(info.getBytes(),
info.getBytes().length, InetAddress.getLocalHost(),8883);
// 发送
ds.send(dp);
// 2、再接收 定义新的接收数据包
byte [] b = new byte[1024];
DatagramPacket dp2 = new DatagramPacket(b,b.length);
ds.receive(dp2);
//接收的数据
System.out.println("接收服务端回复的数据:"+new String(b,0,dp2.getLength()));
}
接收
public static void main(String[] args) throws IOException {
// 1 先接收数据
DatagramSocket ds = new DatagramSocket(8883);
// 需要定义接收的数组
byte [] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b,b.length);
//2 接收
ds.receive(dp);
System.out.println("接收到来自客户端的数据:"+new String(b,0,b.length));
// 2、再回复数据(发送出去)
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要回复的消息:");
String info = sc.nextLine();
DatagramPacket dp2 = new DatagramPacket(info.getBytes(),
info.getBytes().length,
dp.getAddress(), // 对方的ip对象
dp.getPort() // 对方的端口,都在接收的包裹对象上
);
ds.send(dp2);
}
3、点对点的多次聊天
实现多次来回聊天
public static void main(String[] args) throws IOException {
// 1、先发送
DatagramSocket ds = new DatagramSocket();
while(true) {
System.out.println("请输入你要发送的数据 ");
Scanner sc = new Scanner(System.in);
String info = sc.nextLine();
// 将数据打包
DatagramPacket dp = new DatagramPacket(info.getBytes(),
info.getBytes().length, InetAddress.getLocalHost(), 8884);
// 发送
ds.send(dp);
// 2、再接收 定义新的接收数据包
byte[] b = new byte[1024];
DatagramPacket dp2 = new DatagramPacket(b, b.length);
ds.receive(dp2);
//接收的数据
System.out.println("接收服务端回复的数据:" + new String(b, 0, dp2.getLength()));
}
}
接收
public static void main(String[] args) throws IOException {
// 1 先接收数据
DatagramSocket ds = new DatagramSocket(8883);
while(true) {
// 需要定义接收的数组
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b, b.length);
//2 接收
ds.receive(dp);
System.out.println("接收到来自客户端的数据:" + new String(b, 0, b.length));
// 2、再回复数据(发送出去)
Scanner sc = new Scanner(System.in);
System.out.println("请输入你要回复的消息:");
String info = sc.nextLine();
DatagramPacket dp2 = new DatagramPacket(info.getBytes(),
info.getBytes().length,
dp.getAddress(), // 对方的ip对象
dp.getPort() // 对方的端口,都在接收的包裹对象上
);
ds.send(dp2);
}
}