网络
什么是网络?
概念:由点和线构成,表示多个对象之间互相联系
计算机网络:
互联网:Internet
万维网:WWW(World Wide Web)
物联网:IoT(Internet of Things)
网络模型(了解):
OSI参考模型:
应用层:如http协议,SMTP协议(邮件)...
表示层:将数据格式进行传话与加密.
会话层:维持通讯
传输层:如恢复通讯,数据流重用等事情.UDP,TCP
网络层:ip,计算机在互联网的地址
数据链路层:对其数据进行格式化的要求
物理层:硬件设备,如网线,网线接口等
因为OSI过于理想化,所有没有被实现
TCP/IP模型
应用层
对应OSI模型的应用层,表示层,会话层
对应的协议:HTTP,SMTP,HTTPS
传输层
对应OSI模型的传输层
对应的协议:TCP,UDP协议
网络层
对应OSI模型的网络层
对应的协议:IP
网络接口层
对应OSI模型的数据链路层与物理层
对应协议:以太网协议,ADSL协议等
网络编程需要什么?
IP
端口号
通讯协议
IP
概念(重点):计算机在互联网中的地址
IPV4
4个字节,每个字节由8位组成.所以每段的值0~255
0000 0000 ~ 1111 1111
192.168.7.151
IPV6
16个字节,每个字节8位组成,每段16位,所以每段取值范围0~65535
查看当前计算机IP:
步骤:
1.打开dos命令框
2.输入ipconfig
IP地址的分类:
A类地址:大型网络,主要服务于国家与政府企业
B类地址:中型网络,主要服务于大型实验室等
C类地址:个人网络,普通人与普通企业用的网络
特殊IP:(重点)
127.0.0.1表示本机
因为不好记,所以变为了英文localhost
专业名称:回路地址
相关命令:
ipconfig
作用:查看当前计算机的ip信息
ping
作用:尝试连接对方
InetAddress类:
作用:表示计算机在网络中的地址
package ip;
import java.io.IOException;
import java.net.InetAddress;
public class Test {
public static void main(String[] args) throws IOException {
//获取本机的网络地址信息
// InetAddress ip = InetAddress.getLocalHost();
//通过主机名获取别人的地址信息
InetAddress ip = InetAddress.getByName("www.baidu.com");
//通过指定的ip获取对方的信息
// InetAddress ip = InetAddress.getByName("36.152.44.96");
System.out.println(ip);
System.out.println(ip.getHostName()); //获取设备名称
System.out.println(ip.getHostAddress()); //获取ip地址
}
}
运行结果
端口
概念:程序在计算机中的地址
范围:0~65535
注意:
0~1023:一般被系统占用
1024~49151:注册端口
49151~65535:动态端口
常见的端口:
MySQL端口号:3306
Tomcat端口号:8080
HTTP协议端口号:80
Oracle端口号:1521
Redis端口号:6379
通讯协议
TCP
中文名:传输控制协议
特点:面向连接,安全可靠,效率低,基于字节流进行通讯的,传输数据大小无限制
三次握手,四次挥手
第一次握手第一次挥手:客户端向服务器发起请求
第二次握手第二次挥手:判断是否连接成功
第三次握手第三次挥手:客户端上传数据或服务器反馈数据
第四次挥手:客户端断开连接
俗称:打电话
如:去朋友家做客
1.打电话,询问是否方便
对方接听电话(一次握手),打完电话后会挂断电话(一次挥手)
2.去朋友家,敲门
开门(一次握手),朋友倒茶(一次挥手)
3.开始聚会
聊天(一次握手,一次挥手)
4.说拜拜
一次挥手
Java中对应的类:
Socket:客户端
ServerSocket:服务器
UDP
中文名:数据包协议
特点:面向无连接,不安全,效率高,基于数据包格式进行传输,一个数据包最多64kb
俗称:对讲机
如:用对讲机通知同事有小偷
直接对着对讲机说有小偷
基于TCP协议的通讯(掌握)
技术
服务器
创建ServerSocket
等待客户端连接
关闭资源
客户端
创建客户端Socket
关闭资源
案例1:
客户端给服务器发送一条消息
案例2:
客户端给服务器发送一条消息,服务器接收后回复一条消息,客户端接收
案例3:
客户端上传文件给服务器
package tcp01;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器
* 要求: 接收一次客户端消息,打印到控制台
* 步骤:
* 1.创建服务器Socket
* 2.等待客户端连接,获取客户端映射
* 3.通过客户端映射获取其输入流
* 4.使用输入流读取数据
* 5.打印到控制台
* 6.关闭资源,关闭客户端映射,关闭服务器
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.创建服务器Socket
/**
* 参数:该服务器端口号
* 注意:该服务器的ip就是服务器所在计算机的ip地址
*/
ServerSocket server = new ServerSocket(9999);
System.out.println("服务器已启动, 等待客户端连接");
//2.等待客户端连接,获取客户端映射
/**
* 返回值就是客户端映射
* 注意:该方法会阻塞程序,等待客户端连接
*/
Socket socket = server.accept();
//3.通过客户端映射获取其输入流
InputStream is = socket.getInputStream();
//4.使用输入流读取数据
byte[] b = new byte[1024];
int len = 0;
while((len = is.read(b)) != -1) {
String str = new String(b, 0, len);
//5.打印到控制台
System.out.println("客户端说: " + str);
}
//6.关闭资源,关闭客户端映射,关闭服务器
is.close();
socket.close(); //关闭客户端映射
server.close(); //关闭服务器
System.out.println("通讯结束, 服务器关闭");
}
}
package tcp01;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/**
* 客户端
* 要求:客户端给服务器发送一条消息
* 步骤:
* 1.创建客户端的Socket
* 2.获取客户端的输出流
* 3.输出数据
* 4.关闭资源
*/
public class Client {
public static void main(String[] args) throws IOException {
//1.创建客户端的Socket
/**
* 参数1:服务器的地址
* 参数2:服务器的端口号
* 注意:需要先启动服务器,再启动客户端
*/
Socket socket = new Socket("127.0.0.1", 9999);
//2.获取客户端的输出流
OutputStream os = socket.getOutputStream();
//3.输出数据
os.write("你好!".getBytes());
os.flush();
//4.关闭资源
os.close();
socket.close();
}
}
运行结果
package tcp02;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器
* 步骤:
* 1.创建服务器Socket
* 2.等待客户端连接,获取客户端映射
* 3.接收客户端消息
* 1.获取客户端映射的输入流
* 2.通过输入流获取信息
* 4.发送消息给客户端
* 1.获取客户端映射的输出流
* 2.通过输出流回复消息
* 5.关闭资源
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.创建服务器Socket
ServerSocket serverSocket = new ServerSocket(8989);
//2.等待客户端连接, 获取客户端映射
Socket socket = serverSocket.accept();
//3.接收客户端消息
InputStream is = socket.getInputStream();
byte[] b = new byte[1024];
int len = is.read(b);
String str = new String(b, 0, len);
System.out.println("客户端说: " + str);
//4.发送消息给客户端
OutputStream os = socket.getOutputStream();
os.write("收到".getBytes());
os.flush();
//5.关闭资源
os.close();
is.close();
socket.close();
serverSocket.close();
}
}
package tcp02;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* 客户端
* 步骤:
* 1.创建客户端Socket
* 2.发送消息给服务器
* 获取输出流
* 使用输出流发送消息
* 3.接收服务器反馈的消息
* 获取输入流
* 使用输入流接收消息
* 4.关闭资源
*/
public class Client {
public static void main(String[] args) throws IOException {
//1.创建客户端Socket
Socket socket = new Socket("127.0.0.1", 8989);
//2.发送消息给服务器
OutputStream os = socket.getOutputStream();
os.write("服务器你好, 我是客户端".getBytes());
os.flush();
//3.接收服务器反馈的消息
InputStream is = socket.getInputStream();
byte[] b = new byte[1024];
int len = is.read(b);
String str = new String(b, 0, len);
System.out.println("服务器说: " + str);
//4.关闭资源
is.close();
os.close();
socket.close();
}
}
运行结果
package tcp03;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
/**
* 服务器
* 要求:客户端上传图片给服务器
* 步骤:
* 1.创建服务器Socket
* 2.等待客户端连接
* 3.接收客户端上传的文件,并保存
* 4.返回消息给服务器,表示说收到了
* 5.关闭资源
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(7979);
System.out.println("服务器已启动");
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
//生成文件名称, 使用工具类UUID
String name = UUID.randomUUID().toString().replace("-", "");
String file = name + ".png";
//创建文件流存储上传的文件
FileOutputStream fos = new FileOutputStream(file);
byte[] b = new byte[1024];
int len = 0;
//客户端输出流断开后,读取的长度才可以等于-1
while((len = is.read(b)) != -1) {
fos.write(b, 0, len);
fos.flush();
}
fos.close();
System.out.println("客户端上传结束");
OutputStream os = socket.getOutputStream();
os.write("上传成功".getBytes());
os.flush();
os.close();
is.close();
socket.close();
serverSocket.close();
}
}
package tcp03;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
/**
* 客户端
* 要求:上传一个文件给服务器,接收服务器反馈的消息
* 步骤:
* 1.创建客户端Socket
* 2.上传文件
* 3.接收服务器消息
* 4.关闭资源
*/
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 7979);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream("D:\\query.png");
byte[] b = new byte[1024];
int len = 0;
while((len = fis.read(b)) != -1) {
os.write(b, 0, len);
os.flush();
}
//结束客户端输出流
socket.shutdownOutput();
System.out.println("文件上传结束");
//读取服务器反馈的消息
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String str = br.readLine();
System.out.println("服务器说: " + str);
br.close();
fis.close();
os.close();
socket.close();
}
}
运行结果
基于UDP协议的通讯(了解)
技术:
接收端
DatagramSocket(端口号)
接收端对象.receive(数据包):接收数据
发送端
DatagramSocket()
发送端对象.send(数据包):用于发送数据包
数据包
DatagramPacket
案例:
发送端发送一条消息给接收端
package udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* 接收端
* 步骤:
* 1.创建接收端Socket
* 2.创建一个空的数据包,准备接收数据
* 3.接收数据
* 4.关闭资源
*/
public class Receive {
public static void main(String[] args) throws IOException {
//1.创建接收端Socket
DatagramSocket rSocket = new DatagramSocket(10101);
//2.创建一个空的数据包,准备接收数据
byte[] b = new byte[1024];
DatagramPacket packet = new DatagramPacket(b, b.length);
//3.接收数据
rSocket.receive(packet);
//获取包中的数据打印输出
byte[] data = packet.getData(); //获取包中的数据
int length = packet.getLength(); //获取包中的数据长度
String str = new String(data, 0, length);
System.out.println("接收的数据: " + str);
//4.关闭资源
rSocket.close();
}
}
package udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* 发送端
* 步骤:
* 1.创建发送端的Socket
* 2.准备要发送的数据包
* 3.发送数据
* 4.关闭资源
*/
public class Send {
public static void main(String[] args) throws IOException {
//1.创建发送端的Socket
DatagramSocket sSocket = new DatagramSocket();
//2.准备要发送的数据包
byte[] b = "接收端你好, 我是发送端".getBytes();
//接收端ip
InetAddress address = InetAddress.getByName("127.0.0.1");
/**
* 准备要发送的数据包
* 1参:要发送数据所在的数组
* 2参:开始位置
* 3参:发送的字节长度
* 4参:接收端地址
* 5参:接收端端口号
*/
DatagramPacket packet = new DatagramPacket(b, 0, b.length, address, 10101);
//3.发送数据
sSocket.send(packet);
//4.关闭资源
sSocket.close();
}
}
运行结果
练习
使用TCP完成客户端与服务器的多次对话
package tcp04;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9876);
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String str;
Scanner scanner = new Scanner(System.in);
while((str = br.readLine()) != null) {
System.out.println("客户端说: " + str);
System.out.println("请输入你要回复的内容: ");
String input = scanner.nextLine();
os.write((input + "\n").getBytes());
os.flush();
}
br.close();
os.close();
socket.close();
serverSocket.close();
}
}
package tcp04;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("127.0.0.1", 9876);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
os.write("Hello\n".getBytes());
os.flush();
String str;
Scanner scanner = new Scanner(System.in);
while((str = br.readLine()) != null) {
System.out.println("服务器说: " + str);
System.out.println("请输入你要回复的内容: ");
String input = scanner.nextLine();
os.write((input + "\n").getBytes());
os.flush();
}
br.close();
os.close();
socket.close();
}
}
运行结果