写在前面
今天继续讲Java中的网络编程的知识!
网络编程
概述
计算机网络
计算机网络是将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。例如:极域。
网络编程
网络编程是实现网络互连的不同计算机上运行的程序间可以进行数据交换的技术。
网络参考模型图
解释
网络模型7层概述:
-
物理层
- 主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。
- 主要作用是传输比特流(由 1、0 转化为电流强弱来进行传输)。
- 数据单位:比特。
-
数据链路层
- 将从物理层接收的数据进行 MAC 地址的封装与解封装。
- 数据单位:帧。
- 主要设备:交换机。
-
网络层
- 将从下层接收到的数据进行 IP 地址的封装与解封装。
- 数据单位:数据包。
- 主要设备:路由器。
-
传输层
- 定义了数据传输的协议和端口号(如 WWW 端口 80)。
- 主要协议:TCP(传输控制协议)、UDP(用户数据报协议)。
- 数据单位:段。
-
会话层
- 通过传输层建立数据传输的通路,发起或接受会话请求。
- 设备之间需要互相认识(可以是 IP 地址、MAC 地址或主机名)。
-
表示层
- 对接收的数据进行解释、加密与解密、压缩与解压缩等。
- 将计算机能识别的东西转换成人能识别的东西(如图片、声音等)。
-
应用层
- 终端应用,如 FTP(文件下载)、WEB(浏览器)、QQ(聊天)等。
网络通信三要素
-
IP 地址
- 网络中设备的标识,不易记忆,可用主机名。
- IP 地址的组成:网络号码 + 主机地址。
- A 类 IP 地址:
1.0.0.1
—127.255.255.254
。- 例如
10.X.X.X
是私有地址。 127.X.X.X
是保留地址,用做循环测试用的。
- 例如
- B 类 IP 地址:
128.0.0.1
—191.255.255.254
。172.16.0.0
—172.31.255.255
是私有地址。169.254.X.X
是保留地址。
- C 类 IP 地址:
192.0.0.1
—223.255.255.254
。192.168.X.X
是私有地址。
- D 类 IP 地址:
224.0.0.1
—239.255.255.254
(多播地址)。 - E 类 IP 地址:
240.0.0.1
—247.255.255.254
(保留地址)。
查看本机 IP 地址
- DOS 命令:
ipconfig
- CentOS 7:
ip addr
- CentOS 6:
ifconfig
-
端口号
- 用于标识进程的逻辑地址,不同进程的标识。
- 有效端口范围:
0
—65535
,其中0
—1024
为系统使用或保留端口。 - 通过
netstat -ano
可以查看端口号。
-
传输协议
- 通讯的规则。
- 常见协议:TCP、UDP。
InetAddress 类的使用
获取和操作 IP 地址
- 静态方法:使用
InetAddress
类的静态方法获取InetAddress
对象,再进行操作。
方法
-
InetAddress[] getAllByName(String host)
返回指定主机名称的 IP 地址数组。 -
InetAddress getByAddress(byte[] addr)
根据原始 IP 地址返回InetAddress
对象。 -
InetAddress getByAddress(String host, byte[] addr)
根据主机名和 IP 地址创建InetAddress
对象。 -
InetAddress getByName(String host)
确定主机名称的 IP 地址。
Socket
Socket 套接字
- 网络上具有唯一标识的 IP 地址和端口号组合在一起构成套接字。
- Socket 原理机制:通信的两端都有 Socket,通过 IO 流传输数据。
UDP
概述
-
使用
DatagramSocket
和DatagramPacket
进行 UDP 网络编程。 -
步骤:
- 建立 UDP 的 socket 服务。
- 将数据封装成数据包。
- 通过 UDP 的 socket 服务发送数据包。
- 关闭资源。
-
实现:
-
发送端
-
接收端
-
TCP
概述
-
使用
Socket
和ServerSocket
进行 TCP 网络编程。 -
步骤:
- 客户端建立 Socket 服务并连接服务器。
- 建立数据传输通道,通过 IO 流进行数据的读取和写入。
- 关闭资源。
-
实现:
-
客户端
-
服务器端
-
TCP 传输问题
- 问题:客户端连接上服务端,两端都在等待,没有任何数据传输。
- 解决办法:
- 自定义结束标记。
- 使用
shutdownInput
和shutdownOutput
方法。
- 解决办法: