Java基础篇网络编程总结目录
1. 网络编程
1.1 网络编程概述
【说明】
①理解网络编程:
Java提供的网络类库,可以实现 无痛 的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里,由 JVM 进行控制。并且 Java 实现了一个跨平台的网络库,程序员面对的是一个统一的网络编程环境,直接调用方法。
②计算机网络概述:
把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息、共享硬件、软件、数据信息等资源,简单来说就是:通过通信介质将通信设备连接起来,实现信息传递、资源共享。
③网络编程的目的:
直接或间接地通过网络协议与其它计算机实现数据交换,进行通讯。
⑤实现网络编程的两个要点:
(1)通过使用套接字{IP地址,端口号}通过IP地址定位到网络上通信的主机,使用端口号确定通信的进程。
(2)通过使用协议来确定再进行数据传输时的规则,例如:通信速率,传输代码、代码结构、传输控制步骤、出错控制等制定标准。
1.2 IP地址和端口号
IP地址概述
①唯一的标识 Internet 上的计算机
②本地回环地址(hostAddress):127.0.0.1 主机名(hostName):localhost
③IP地址分为IPv4和IPv6,其中IPv4一共32位,IPv6一共123位
④IP地址分类方式2:公网地址(万维网使用)和私有地址(局域网使用)。192.168.开头的就是私有址址,范围即为192.168.0.0–192.168.255.255,专门为组织机构内部使用
IPv4分类规则:
IP地址根据网络号和主机号来分,分为A、B、C三类及特殊地址D、E。 全0和全1的都保留不用。
IPv4地址划分 | 范围 |
---|---|
A类 | 1.0.0.0-126.0.0.0 |
B类 | 128.0.0.0-191.255.0.0 |
C类 | 192.0.0.0-223.255.255.0 |
D类 | 多播地址网络号取值于224~239之间 |
E类 | 保留地址网络号取值于240~255之间 |
端口号概述
①端口号标识正在计算机上运行的进程(程序)
②不同的进程有不同的端口号
③被规定为一个 16 位的整数 0~65535
端口号分类
分类 | 范围 |
---|---|
熟知端口 | 0-1023 |
登记端口 | 1024-49151 |
短暂端口(用户使用) | 49152-65535 |
1.3 InetAddress类
InetAddress类的功能:获取IP地址,为下面的TCP和UDP实现通信打造基础。
Internet上的主机有两种方式表示地址:
①域名(hostName):www.atguigu.com
②IP 地址(hostAddress):192.168.10.100
InetAddress类的实例化:
方式一: getByName(String host)
方式二: getLocalHost()
InetAddress类的 常用方法:
方法名 | 说明 |
---|---|
getHostAddress() | 返回 IP 地址字符串(以文本表现形式) |
getHostName() | 获取此 IP 地址的主机名 |
isReachable(int timeout) | 测试是否可以达到该地址 |
使用代码示例:
public class InetAddressTest {
public static void main(String[] args) {
try {
InetAddress inet1 =InetAddress.getByName("192.168.12.23");
System.out.println(inet1);
InetAddress inet2 = InetAddress.getByName("www.baidu.com");//需要根据域名,解析出其对应的IP地址
System.out.println(inet2);
InetAddress inet3 = InetAddress.getLocalHost();
System.out.println(inet3);//获取本机的IP地址
System.out.println(inet2.getHostAddress());//获取IP地址
System.out.println(inet2.getHostName());//获取域名
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
2. 网络通信编程
2.1 TCP网络编程
协议说明:
①使用TCP协议前,须先建立TCP连接,形成传输数据通道
②传输前,采用“三次握手”方式,点对点通信,是可靠的
③TCP协议进行通信的两个应用进程:客户端、服务端。
④在连接中可进行大数据量的传输
⑤传输完毕,需释放已建立的连接,效率低
2.1.1 TCP三次握手
实现的文字描述+图示:
实现过程
第一次握手:客户端应用进程 主动打开,向服务器端发送连接建立请求,其中首部SYN = 1,seq = x;(SYN表示连接建立请求,seq表示当前发送数据包的序号)
第二次握手:服务器端应用进程被动打开,如果同意连接建立请求,就发回确认报文,其中首部SYN = 1,seq = y,ack = x + 1; ACK = 1(ack:表示希望收到对方下一个数据包的序号,ACK = 1时,ack有效,它是一个标识位)
第三次握手:客户端收到服务器端的确认报文之后就通知上层应用进程 连接已建立,并且发挥确认报文,当服务器端收到确认报文之后,也通知上层应用进程连接已建立,其中首部:(ACK = 1,seq = y + 1,ack = x + 1)
2.1.2 TCP四次挥手
实现四次挥手的文字描述+图示
实现过程:
第一次挥手:客户端主动关闭连接,停止发送数据,发送关闭连接请求,其中首部FIN = 1,ACK = 1,seq = u(FIN为关闭连接请求)
第二次挥手:服务器端发挥确认报文,这时候从客户端到服务器端的连接就被关闭,处于一个半连接状态,其中首部:ACK = 1,seq = v,ack = u + 1
第三次挥手:服务器端再发完数据时,主动关闭连接,此时首部FIN = 1 ,ACK = 1,seq = w,ack = u+1(在这一个过程中发送方一直没有发送数据,所以确认号还是u + 1)
第四次挥手:客户端收到服务器端的报文之后,设置等待计时器2MSL后,彻底关闭连接,其中首部ACK = 1,seq = w + 1,ack = u + 1
2.1.3 基于Socket的TCP编程
实现步骤:
①创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
②打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输
③按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
④关闭 Socket:断开客户端到服务器的连接,释放线路
实现样例:
客户端发送文件给服务端,服务端将文件保存在本地。
@Test
public void client() {
Socket socket = null;
OutputStream os = null;
BufferedInputStream bis = null;
try {
//1.指明服务器端的IP地址
InetAddress inet = InetAddress.getByName("127.0.0.1");
//2.创建套接字对象,用来获取一个输出流
socket = new Socket(inet, 9090);
//3.获取输出流
os = socket.getOutputStream();
//4.由于是文件,所以需要创建一个节点流,这里为了效率高一些,使用缓冲流处理
FileInputStream fis = new FileInputStream(new File("爱情与友情.jpg"));
bis = new BufferedInputStream(fis);
//5.文件传出
byte[] buffer = new byte[10];
int len;
while ((len = bis.read(buffer)) != -1){
os.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务器端:
@Test
public void server() {
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
BufferedOutputStream bos = null;
try {
//1.创建一个ServerSocket对象
ss = new ServerSocket(9090);
socket = ss.accept();
//2.获取输入流
is = socket.getInputStream();
//3.指明读取文件
bos = new BufferedOutputStream(new FileOutputStream(new File("爱情与友情2.jpg")));
//4.实现数据传输
byte[] buffer = new byte[5];
int len;
while ((len = is.read(buffer)) != -1){
bos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//5.实现流资源的关闭
if (bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null){
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
实现结果
2.2 UDP网络编程
2.2.1 UDP通信
协议传输特点:
①将数据、源、目的封装成数据包,不需要建立连接
②每个数据报的大小限制在64K内
③ 发送不管对方是否准备好,直接发送数据,接收方收到也不确认,故是不可靠的
④可以广播发送
⑤发送数据结束时无需释放资源,开销小,速度快
2.2.2 UDP通信实现流程
说明:
①DatagramSocket与DatagramPacket(使用的两个类)
②建立发送端,接收端
③建立数据包
④调用Socket的发送send()、接收方法receive()
⑤关闭Socket
2.2.3 UDP实现通信
实现内容:
发送方给接收方发送:我是UDP方式发送的数据,接收方在控制台打印
发送方
@Test
public void sender() throws IOException {
DatagramSocket socket = new DatagramSocket();
String str = "我是UDP方式发送的数据";
byte[] data = str.getBytes();
InetAddress inet = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);
socket.send(packet);
socket.close();
}
接收方
@Test
public void receiver() throws IOException {
DatagramSocket socket = new DatagramSocket(9090);
byte[] buffer = new byte[100];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
}
实现结果:
2.3 URL编程
2.3.1 URL概述
说明
①URL(Uniform Resource Locator):统一资源定位符,它表示 Internet 上某一资源的地址。
②通过 URL 我们可以访问 Internet 上的各种网络资源,比如最常见的 www,ftp 站点
③基本结构
<传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表
样例:http://localhost:8080/examples/cartoon.jpg
2.3.2 URL构造器及常用方法
构造器
URL url = new URL(“填写路径”);
实现样例
URL url = new URL(“http://localhost:8080/examples/hello.txt/username=Tom”);
常用方法
方法名 | 说明 |
---|---|
getProtocol( ) | 获取该URL的协议名 |
getHost( ) | 获取该URL的主机名 |
getPort( ) | 获取该URL的端口号 |
getPath( ) | 获取该URL的文件路径 |
getFile( ) | 获取该URL的文件名 |
getQuery( ) | 获取该URL的查询名 |
2.3.3 URL编程实现
使用样例
通过启动tomcat服务器,把cartoon.jpg图片上传到服务器,利用URL实现对服务器照片的下载;
实现步骤:
①创建URL对象(指明要下载文件的位置)
②打开连接
③建立连接
④获取节点流
⑤实现对文件的读入和写出
⑥关闭流资源
实现
public class URLTest1 {
public static void main(String[] args) {
HttpURLConnection urlConnection = null;
InputStream is = null;
FileOutputStream fos = null;
try {
URL url = new URL("http://localhost:8080/examples/cartoon.jpg");
//打开连接
urlConnection = (HttpURLConnection) url.openConnection();
//建立连接
urlConnection.connect();
//获取读入流
is = urlConnection.getInputStream();
//创建写出流
fos = new FileOutputStream(new File("url.jpg"));
//读入写出过程
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//资源关闭
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (urlConnection != null){
urlConnection.disconnect();
}
}
}
}
实现结果