文章标题:
Java基础网络编程新探索
文章内容:
目录
- 一、网络通信的关键要素
- 1、要素其一:IP地址与域名
- 1.1、IP地址
- IP地址:即互联网协议地址(Internet Protocol Address),俗称
IP
- IP地址是为网络中每台计算机设备赋予的唯一标识
- IP地址:即互联网协议地址(Internet Protocol Address),俗称
IP地址的分类方式一
* **`IPv4`:是一个32位的二进制数,通常被划分为4个字节**
* **以点分十进制形式表示,例如`192.168.65.100`**
* **其中a、b、c、d均为0~255之间的十进制整数**
* 这种方式最多可表示约42亿个地址。其中北美约占30亿,亚洲4亿,中国2.9亿。`2011年初已用尽`
* **IP地址由网络地址和主机地址组成**
* **网络地址:标识计算机或网络设备所在的网段**
* **主机地址:标识特定的主机或网络设备**
* **`IPv6`:为扩充地址空间,拟通过IPv6重新定义地址空间,采用128位地址长度,共16个字节**
* **由8个无符号整数构成,每个整数用四个十六进制位表示,数间用冒号:分隔。例如:`ABCD:EF01:2345:6789:ABCD:EF01:2345:6789`**
IP地址的分类方式二
* **公网地址(用于万维网)和私有地址(用于局域网)**
* 1.2、域名
* **Internet上主机有两种地址表示方式:**
* **域名(hostName):如www.baidu.com**
* **IP 地址(hostAddress):如202.108.35.210**
* **域名解析:因IP地址数字不便于记忆,遂出现域名**
* **域名易记,连接网络时输入主机域名**
* **域名服务器(DNS,Domain Name System,域名系统)负责将`域名转换为IP地址`**
简单理解:
* 2、要素其二:端口号
* **若IP地址可唯一标识网络中的设备,那么端口号可唯一标识设备中的进程(应用程序)**
* **不同进程设置不同端口号**
* **`端口号`:由两个字节表示的整数,取值范围为`0~65535`**
* **公认端口:0~1023。被预先定义的服务通信占用,如:HTTP(80),FTP(21),Telnet(23)**
* **注册端口:1024~49151。分配给用户进程或应用程序。如:Tomcat(8080),MySQL(3306),Oracle(1521)**
* **动态/私有端口:49152~65535**
* **若端口号被其他服务或应用占用,会导致当前程序启动失败**
* 3、要素其三:网络通信协议
* **`网络通信协议`:计算机网络中连接与通信的规则,称为网络通信协议**
* **对数据传输格式、速率、步骤、出错控制等做统一规定**
* **通信双方须同时遵守方能完成数据交换**
* **存在两套参考模型:**
* **OSI参考模型:模型过于理想化,未在因特网上广泛推广**
* **TCP/IP参考模型(或TCP/IP协议):事实上的国际标准**
* **TCP/IP协议:** 传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol),TCP/IP以其两大主要协议:传输控制协议(TCP)和网络互联协议(IP)得名
TCP/IP协议中的四层介绍:
* `应用层`:决定向用户提供应用服务时的通信活动。主要协议有:HTTP协议、FTP协议、SNMP(简单网络管理协议)、SMTP(简单邮件传输协议)和POP3(邮局协议第3版)等
* `传输层`:使网络程序通信,网络通信可采用TCP或UDP协议。TCP(传输控制协议)是面向连接、可靠、基于字节流的传输层通信协议。UDP(User Datagram Protocol,用户数据报协议):是无连接的传输层协议,提供面向事务的简单不可靠信息传送服务
* `网络层`:TCP/IP协议核心,支持网间互连数据通信。主要用于将传输数据分组并发送至目标计算机或网络。IP协议至关重要,IP(internet protocal)又称互联网协议,负责将数据从源传至目的地,在源地址和目的地址间传送数据包,还提供数据大小重新组装功能以适应不同网络对包大小的要求
* `物理+数据链路层`:链路层定义物理传输通道,通常是某些网络连接设备的驱动协议,例如针对光纤、网线的驱动协议
二、传输层协议:TCP与UDP协议
java.net
包提供两种常见网络协议支持:- UDP :用户数据报协议(User Datagram Protocol)
- TCP :传输控制协议 (Transmission Control Protocol)
1、TCP协议
- TCP协议通信的两个应用进程:客户端、服务端
- 使用TCP协议前,需先
建立TCP连接
,形成基于字节流的传输数据通道 - 传输前采用“三次握手”方式,点对点通信,是
可靠的
- TCP协议使用重发机制,一通信实体发送消息给另一通信实体后,需收到另一通信实体确认信息
- 未收到确认信息则重复发送消息
- 可进行
大数据量传输
- 传输完毕需
释放已建立连接,效率低
- 适用场景:打电话
2、UDP协议
- UDP协议通信的两个应用进程:发送端、接收端
- 将数据、源、目的封装成数据包(传输基本单位),
无需建立连接
- 发送不论对方是否准备好,接收方收到不确认,不能保证数据完整性,故是
不可靠的
- 每个数据报大小限制在
64K
内 - 发送数据结束时
无需释放资源,开销小,通信效率高
- 适用场景:音频、视频和普通数据传输。例如视频会议
3、三次握手
- TCP协议中,发送数据准备阶段,客户端与服务器间的
三次交互
以保证连接可靠- 第一次握手,客户端向服务器发起TCP连接请求(
客户端请求连接
) - 第二次握手,服务器发送针对客户端TCP连接请求的确认(
服务端收到
) - 第三次握手,客户端发送确认的确认 (
客户端知服务端已收到
)
- 第一次握手,客户端向服务器发起TCP连接请求(
4、四次挥手
- TCP协议中,发送数据结束后释放连接需经四次挥手
- 第一次挥手:客户端向服务器提出结束连接,让服务器做最后准备工作。此时客户端处半关闭状态,即不再向服务器发送数据,但可接收数据(
客户端请求关闭
) - 第二次挥手:服务器接收到客户端释放连接请求后,将最后数据发给客户端,并告知上层应用进程不再接收数据(
服务端收到
) - 第三次挥手:服务器发送完数据后,给客户端发送释放连接报文。客户端接收后知可正式释放连接(
服务端请求关闭
) - 第四次挥手:客户端接收到服务器最后释放连接报文后,回复彻底断开报文。服务器收到后彻底释放连接。客户端发送完最后报文后,等待2MSL,因服务器可能未收到最后报文,若服务器迟迟未收到,会再次发送释放连接报文,此时客户端在等待时间内接收,会重新发送最后报文并重新计时。若等待2MSL后未收到,彻底断开(
客户端收到
)
- 第一次挥手:客户端向服务器提出结束连接,让服务器做最后准备工作。此时客户端处半关闭状态,即不再向服务器发送数据,但可接收数据(
三、网络编程API
1、InetAddress类
- InetAddress类主要表示IP地址,有两个子类:Inet4Address、Inet6Address
- InetAddress 类无公共构造器,提供以下静态方法获取InetAddress实例
- public static InetAddress getLocalHost()
- public static InetAddress getByName(String host)
- public static InetAddress getByAddress(byte[] addr)
- InetAddress 提供以下常用方法
- public String getHostAddress() :返回IP地址字符串
- public String getHostName() :获取此IP地址的主机名或域名
public class TestInetAddress {
public static void main(String[] args) throws Exception {
//1. 获取本机的InetAddress 对象
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);//DESKTOP-S4MP84S/192.168.12.1
//2. 根据指定主机名 获取 InetAddress对象
InetAddress host1 = InetAddress.getByName("DESKTOP-S4MP84S");
System.out.println("host1=" + host1);//DESKTOP-S4MP84S/192.168.12.1
//3. 根据域名返回 InetAddress对象, 比如 www.baidu.com 对应
InetAddress host2 = InetAddress.getByName("www.baidu.com");
System.out.println("host2=" + host2);//www.baidu.com / 110.242.68.4
//4. 通过 InetAddress 对象,获取对应的地址
String hostAddress = host2.getHostAddress();//IP 110.242.68.4
System.out.println("host2 对应的ip = " + hostAddress);//110.242.68.4
//5. 通过 InetAddress 对象,获取对应的主机名/或者的域名
String hostName = host2.getHostName();
System.out.println("host2对应的主机名/域名=" + hostName); // www.baidu.com
}
}
2、Socket类
- 网络上具唯一标识的
IP地址
和端口号
组合构成唯一能识别的标识符套接字(Socket
) - 通信两端均需Socket,是两台机器间通信端点
- Socket允许程序将网络连接当作流,数据在两个Socket间通过
IO
传输 - 一般主动发起通信的应用程序为客户端,等待通信请求的为服务端
- Socket分类:
- 流套接字(stream socket):使用
TCP
提供可靠字节流服务 - 数据报套接字(datagram socket):使用
UDP
提供“尽力而为”数据报服务
- 流套接字(stream socket):使用
3、TCP编程
通信模型
开发步骤
服务端:
* ServerSocket(int port)
:创建服务器端套接字ServerSocket并绑定指定端口,监听客户端请求
* 调用ServerSocket对象accept()
方法:监听连接请求,客户端请求连接则接受,返回通信套接字对象Socket
* 调用该Socket 类对象的 getOutputStream() 和 getInputStream () :获取输出流和输入流,开始网络数据发送接收
* 关闭Socket 对象:客户端访问结束,关闭通信套接字
客户端:
* Socket(InetAddress address, int port)
:根据指定服务端IP地址
和端口号
构造Socket类对象
* 若服务器端响应,则建立客户端到服务器通信线路
* 若连接失败,出现异常
* 打开连接到Socket的输入/出流:使用 getInputStream()方法获输入流,使用getOutputStream()方法获输出流,进行数据传输
* 通过输入流读取服务器放入线路信息(不能读取自己放入信息)
* 通过输出流将信息写入线路
* 关闭Socket:断开客户端到服务器连接,释放线路
例子:从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端
服务端:
* ServerSocket对象可通过 accept() 返回多个Socket
[多个客户端连接服务器的并发]
* 无客户端连接9090端口时,程序一直阻塞
, 等待连接
@Test
public void server() throws IOException {
// 1. 创建ServerSocket
int port = 9090;
ServerSocket serverSocket = new ServerSocket(port);
// 2. 接收来自于客户端的socket:accept()
Socket socket = serverSocket.accept();
// 3. 通过Socket获取一个输入流
InputStream is = socket.getInputStream();
// 4. 创建File类的实例、FileOutputStream的实例
File file = new File("pic_copy2.jpg");
FileOutputStream fos = new FileOutputStream(file);
// 5. 读写过程
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("数据接收完毕");
// 6. 服务端发送数据给客户端
OutputStream os = socket.getOutputStream();
os.write("你的图片很漂亮,我接收到了".getBytes());
// 7. 关闭相关的Socket和流
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
客户端:
* socket.shutdownOutput()
:客户端表明不再继续发送数据,否则对方读操作一直阻塞
@Test
public void client() throws IOException {
// 1. 创建Socket
// 指明对方(即为服务器端)的ip地址和端口号
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
int port = 9090;
Socket socket = new Socket(inetAddress, port);
// 2. 创建File的实例、FileInputStream的实例
File file = new File("pic.jpg");
FileInputStream fis = new FileInputStream(file);
// 3. 通过Socket,获取输出流
OutputStream os = socket.getOutputStream();
// 4. 读写数据
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
System.out.println("数据发送完毕");
// 客户端表明不再继续发送数据,否则对方读操作会一直处于阻塞状态
socket.shutdownOutput();
// 5. 接收来着于服务器端的数据
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer1 = new byte[5];
int len1;
while ((len1 = is.read(buffer1)) != -1) {
baos.write(buffer1, 0, len1);
}
System.out.println(baos.toString());
// 6. 关闭Socket和相关的流
baos.close();
is.close();
os.close();
fis.close();
socket.close();
}
4、UDP编程
通信模型
* UDP(User Datagram Protocol,用户数据报协议):无连接传输层协议,提供面向事务简单不可靠信息传送服务,类似短信、视频通话
* **UDP适用于一次只传少量
文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/12643.html