韩顺平循序渐进学Java零基础 第21章 网络编程
Posted Spring-_-Bear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了韩顺平循序渐进学Java零基础 第21章 网络编程相关的知识,希望对你有一定的参考价值。
第21章 网络编程
662. 网络相关概念
663. IP地址
- IP 地址概念: 用于唯一标识网络中的每台计算机(主机)
- DOS 查看 IP 地址:ipconfig
- IPV4 用 4 字节共 32 位标识一个 IP 地址(点分十进制)
- IPV6 用 8 字节共 128 位标识一个 IP 地址
- IP 地址的组成:网络地址 + 主机地址
- IPV4 的分类:127.0.0.1 表示本机地址
分类 | 表示方法 | 范围 |
---|---|---|
A | 0 + 7 位网络号 + 24 位主机号 | 0.0.0.0 ~ 127.255.255.255 |
B | 10 + 14 位网络号 + 16 位主机号 | 128.0.0.0 ~ 191.255.255.255 |
C | 110 + 21 位网络号 + 8 位主机号 | 192.0.0.0 ~ 223.255.255.255 |
D | 1110 + 28 位多播组号 | 224.0.0.0 ~ 239.255.255.255 |
E | 11110 + 27 位留待后用 | 240.0.0.0 ~ 247.255.255.255 |
664. 域名和端口
- 域名:将 IP 地址映射成域名(http 协议)
- 端口:用于标识计算机上特定的网络程序,以整数形式表示,范围是 0 ~ 65535,其中 0 ~ 1024 已被占用。常见的网络程序端口:ssh 22;ftp 21;smtp 25;http 80;tomcat 8080;mysql 3306;oracle 1521;sql server 1433
665. 网络协议
- TCP / IP(Transmission Control Protocol / Internet Protocol):传输控制协议 / 因特网互联协议,又名网络通讯协议
TCP/IP模型 | 对应协议 |
---|---|
应用层 | http、ftp、telnet、DNS··· |
传输层 | TCP、UDP··· |
网络层 | IP、ICMP、ARP··· |
物理 + 数据链路层 | Link |
666. TCP和UDP
- TCP(Transmission Control Protocol):在使用 TCP 协议前,须先建立 TCP 连接,形成传输数据通道;传输前,采用 ”三次握手“ 方式建立连接,传输可靠;TCP 协议进行通信的两个应用程序:客户端、服务端;在连接中可进行大量数据的传输;传输完毕,需释放已建立的连接,效率较低
- UDP(User Data Protocol):将数据、源、目的封装成数据包,不需要建立连接,传输不可靠,无需释放资源,速度快;每个数据包的大小限制在 64K 以内
667. InetAddress
方法名 | 功能 |
---|---|
getLocalHost | 获取本机 InetAddress 对象 |
getByName | 根据指定主机名 / 域名获取 InetAddress 对象 |
getHostName | 获取 InetAddress 对象的主机名 |
getHostAddress | 获取 InetAddress 对象的 ip 地址 |
// 获取本机的 InetAddress 对象
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
// 根据指定主机名/域名获取 InetAddress 对象
InetAddress csdn = InetAddress.getByName("www.csdn.net");
System.out.println(csdn);
InetAddress springBear = InetAddress.getByName("SpringBear");
System.out.println(springBear);
// 获取 InetAddress 对象的主机名
System.out.println(localHost.getHostName());
System.out.println(csdn.getHostName());
// 获取 InetAddress 对象的 ip 地址
System.out.println(springBear.getHostAddress());
System.out.println(csdn.getHostAddress());
668. Socket
- Socket(套接字)开发网络应用程序时被广泛使用,以至于成为事实上的标准;通信的两端都要有 Socket,是两台机器间通信的端点;网络通信其实就是 Socket 间的通信;Socket 允许程序把网络连接当作是一个流,数据在两个 Socket 间通过 IO 传输;一般发起通信的应用程序属客户端,等待通信请求的为服务端
669. TCP字节流编程1
- Server
// 监听端口
ServerSocket serverSocket = new ServerSocket(4444);
// 等待连接
Socket socket = serverSocket.accept();
// 从数据通道中读取数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen;
while ((readLen = inputStream.read(buf)) != -1)
System.out.println(new String(buf, 0, readLen));
// 关闭资源
inputStream.close();
socket.close();
serverSocket.close();
- Client
// 建立连接
Socket socket = new Socket(InetAddress.getLocalHost(), 4444);
// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello,Server!".getBytes(StandardCharsets.UTF_8));
// 关闭资源
outputStream.close();
socket.close();
670. TCP字节流编程2
- Server
// 监听端口
ServerSocket serverSocket = new ServerSocket(5555);
// 等待连接
Socket socket = serverSocket.accept();
// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen;
while ((readLen = inputStream.read(buf)) != -1)
System.out.println(new String(buf, 0, readLen));
// 关闭 socket 的输入流
socket.shutdownInput();
// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello,Client!".getBytes(StandardCharsets.UTF_8));
// 关闭资源
outputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
- Client
// 建立连接
Socket socket = new Socket(InetAddress.getLocalHost(), 5555);
// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello,Server!".getBytes(StandardCharsets.UTF_8));
// 关闭 socket 的输出流
socket.shutdownOutput();
// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen;
while ((readLen = inputStream.read(buf)) != -1)
System.out.println(new String(buf, 0, readLen));
// 关闭资源
inputStream.close();
outputStream.close();
socket.close();
671. TCP字符流编程
- Server
// 监听端口
ServerSocket serverSocket = new ServerSocket(6666);
// 等待连接
Socket socket = serverSocket.accept();
// 从数据通道读取信息
InputStream inputStream = socket.getInputStream();
// 字节输入流转换成字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(bufferedReader.readLine());
// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
// 字节输出流转换成字符输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("Hello,Client!");
// 行分隔符,写入结束标志
bufferedWriter.newLine();
// 刷新缓冲区,写入数据通道
bufferedWriter.flush();
// 关闭资源
bufferedWriter.close();
bufferedReader.close();
socket.close();
serverSocket.close();
- Client
// 建立连接
Socket socket = new Socket(InetAddress.getLocalHost(), 6666);
// 写入数据到数据通道
OutputStream outputStream = socket.getOutputStream();
// 字符输出流转换从字节输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("Hello,Server!");
// 行分隔符,写入结束标记
bufferedWriter.newLine();
// 刷新缓冲区,写入数据通道
bufferedWriter.flush();
// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
// 字节输入流转换成字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(bufferedReader.readLine());
// 关闭资源
bufferedReader.close();
bufferedWriter.close();
socket.close();
672. 网络上传文件1
673. 网络上传文件2
674. 网络上传文件3
- Server
File saveFilePath = new File("C:\\\\Users\\\\Admin\\\\Desktop\\\\temp.jpg");
// 从数据通道中读取源文件字节数组
ServerSocket serverSocket = new ServerSocket(5555);
Socket socket = serverSocket.accept();
InputStream socketInputStream = socket.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int readLen;
byte[] buf = new byte[1024];
while ((readLen = socketInputStream.read(buf)) != -1)
byteArrayOutputStream.write(buf, 0, readLen);
buf = byteArrayOutputStream.toByteArray();
socket.shutdownInput();
// 将接收到的字节数组写入磁盘
FileOutputStream fileOutputStream = new FileOutputStream(saveFilePath);
fileOutputStream.write(buf);
// 向客户端反馈消息
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write("Receive file successfully!".getBytes(StandardCharsets.UTF_8));
socket.shutdownOutput();
socketOutputStream.close();
fileOutputStream.close();
byteArrayOutputStream.close();
socketInputStream.close();
socket.close();
serverSocket.close();
- Client
File sourceFilePath = new File("C:\\\\Users\\\\Admin\\\\Desktop\\\\fishing.jpg");
// 从磁盘中读取源文件存入字节数组
int readLen;
byte[] buf = new byte[1024];
FileInputStream fileInputStream = new FileInputStream(sourceFilePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((readLen = fileInputStream.read(buf)) != -1)
byteArrayOutputStream.write(buf, 0, readLen);
buf = byteArrayOutputStream.toByteArray();
// 发送源文件字节数组到数据通道
Socket socket = new Socket(InetAddress.getLocalHost(), 5555);
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write(buf);
socket.shutdownOutput();
// 从数据通道读取服务器反馈的消息
InputStream socketInputStream = socket.getInputStream();
while ((readLen = socketInputStream.read(buf)) != -1)
System.out.println(new String(buf, 0, readLen));
socketInputStream.close();
socketOutputStream.close();
socket.close();
byteArrayOutputStream.close();
fileInputStream.close();
675. netstat
-
netstat -an:可以查看当前主机网络情况,包括端口监听和网络连接情况:
-
netstat -anb:管理员身份运行可以查看监听端口的程序
-
命令后跟参数 | more 可以进行分页显示;ctrl + c(double) 可以退出查看
676. TCP链接秘密
- 当客户端与服务端建立连接后,实际上客户端也是通过一个端口与服务端进行通信的,这个端口号是根据 TCP / IP 由系统随机分配的
Proto | Local Address | Foreign Address | State |
---|---|---|---|
TCP | 10.138.141.42:5555 | 10.138.141.42:52820 | ESTABLISHED |
677. UDP原理
- UDP 编程没有明确的服务端和客户端,因此无需建立连接
- UDP 数据包通过数据包套接字 DatagramSocket 实现发送和接收,系统不保证 UDP 数据包一定送达目的地,也不确定什么时候可以送达
- DatagramSocket 对象封装了 UDP 数据包,在数据包中封装了数据、发送端和接收端的 IP 地址以及端口信息
678. UDP网络编程1
679. UDP网络编程2
- Receiver
// 监听端口
DatagramSocket socket = new DatagramSocket(7777);
// 接收包
// 用户保存数据包的缓冲区
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// 拆包,获取数据
int dataLen = packet.getLength();
byte[] data = packet.getData();
System.out.println(new String(data, 0, dataLen));
// 装包,封装数据
buf = "Hello, sender!".getBytes(StandardCharsets.UTF_8);
packet = new DatagramPacket(buf, 0, buf.length, InetAddress.getLocalHost(), 8888);
// 发送包
socket.send(packet);
// 关闭资源
socket.close();
- Sender
// 监听端口
DatagramSocket socket = new DatagramSocket(8888);
// 装包,封装数据
byte[] data = "Hello, receiver!".getBytes(StandardCharsets.UTF_8);
DatagramPacket packet = new DatagramPacket(data, 0, data.length, InetAddress.getLocalHost(), 7777);
// 发送包
socket.send(packet);
// 接收包
// 用于保存数据包的缓冲区
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// 拆包,获取数据
int dataLen = packet.getLength();
data = packet.getData();
System.out.println(new String(data, 0, dataLen));
// 关闭资源
socket.close();
680. 网络编程作业1
681. 网络编程作业2
682. TCP文件下载1
683. TCP文件下载2
684. 网络编程梳理
以上是关于韩顺平循序渐进学Java零基础 第21章 网络编程的主要内容,如果未能解决你的问题,请参考以下文章
韩顺平循序渐进学Java零基础 第10章 面向对象编程(高级部分)