(笔记)网络编程
1.1 概述
1.1.1 介绍
网络编程
指通过计算机网络进行数据传输和通信的编程技术。它涉及到在不同计算机之间建立连接、传输数据、接收数据、处理数据等操作。
在网络编程中,通常涉及两个主要的角色:客户端和服务器。客户端是请求数据的一方,而服务器是提供数据的一方。客户端和服务器之间通过网络进行通信,交换数据以完成特定的任务。
网络编程通常基于一系列的协议,例如传输控制协议(TCP)、用户数据报协议(UDP)、超文本传输协议(HTTP)等。这些协议定义了在网络上如何进行数据传输和通信的规则和规范。
在进行网络编程时,需要使用特定的编程语言和工具来实现网络连接、数据传输和通信等功能。例如,使用 Java 可以使用 Socket 类和相关类库来进行网络编程,使用 Python 可以使用 socket 模块来进行网络编程,而使用 Golang 可以使用 net 包和相关库来进行网络编程。
网络编程的应用非常广泛,包括但不限于以下领域:
- 网络通信和消息传递:通过网络进行消息传递、实时通信、远程过程调用等。
- 客户端-服务器应用程序:构建基于客户端-服务器模型的应用程序,例如网站、聊天应用等。
- 分布式系统和云计算:设计和构建分布式系统,并通过网络进行协调和通信。
- 网络安全:开发网络安全应用程序,例如防火墙、入侵检测系统等。
总之,网络编程是指在计算机网络中进行数据传输和通信的编程技术。它是构建现代网络应用和系统的重要组成部分,通过网络编程可以实现各种实时通信、分布式计算、网站开发和网络安全等应用。
【狂神说Java】网络编程实战讲解_哔哩哔哩_bilibili
计算机网络
计算机网络是指将多台计算机通过通信设备互相连接在一起,以实现数据和资源共享、通信和协作的系统。它是现代计算机系统中重要的组成部分,为人们提供了信息交流、远程访问、资源共享等便利。
计算机网络的基本组成包括以下几个要素:
-
网络设备:包括计算机、服务器、路由器、交换机、调制解调器等,这些设备用于数据交换、连接和路由。
-
通信介质:指物理连接设备之间的传输介质,如光纤、电缆、无线信道等,用于传输数据信号。
-
网络协议:指计算机在网络中进行通信时遵循的规则和约定,例如传输控制协议(TCP)、互联网协议(IP)、以太网协议等。
-
网络拓扑:指计算机网络中设备和连接之间的布局和结构,如星型拓扑、总线拓扑、环状拓扑等。
根据规模和范围的不同,计算机网络可以分为局域网(LAN)、城域网(MAN)、广域网(WAN)以及互联网(Internet)。局域网是在一个相对较小的地理范围内建立起来的网络,例如家庭、办公室等;城域网则覆盖了一个城市或地区;广域网是连接跨越较大地理范围的网络,如跨国、跨城市的网络;而互联网是一个全球性的计算机网络,包括无数的网络设备和大量的用户。
计算机网络的应用非常广泛,包括但不限于以下领域:
- 通信和消息传递:通过计算机网络实现即时通信、电子邮件、视频会议等。
- 网络服务和资源共享:通过网络共享文件、打印机、数据库等资源。
- 远程访问和控制:通过网络远程访问计算机和服务器,进行文件传输、远程控制等。
- 互联网应用和电子商务:通过互联网提供在线服务、网站、电子商务等。
- 云计算和分布式系统:利用计算机网络构建分布式系统和云计算平台。
总之,计算机网络是通过连接多台计算机和设备,在一起实现数据和资源共享、通信和协作的系统。它在现代社会中发挥着重要的作用,支持了各种通信、共享和远程访问的需求,使得人们更容易地获取和利用信息。
1.1.2 目的
网络编程的目的是使用计算机网络进行数据传输和通信,以实现特定的功能和需求。它可以在不同的计算机之间传送数据,并提供实时通信、远程访问、资源共享等功能。
以下是网络编程的几个主要目的:
- 数据传输:网络编程提供了一种可靠的方式来传输数据。通过网络编程,可以将数据从一个计算机发送到另一个计算机,无论是在局域网内还是在广域网上。例如聊天应用、即时通信应用(如WhatsApp、微信)、视频会议应用(如Zoom、Microsoft Teams)等。这些应用允许用户在不同的计算机上进行实时通信,通过网络传输文本消息、语音数据、视频流等。
- 远程访问:网络编程使得远程访问成为可能。通过网络连接,可以远程访问和控制远程计算机或服务器,从而执行操作、获取文件、运行程序等。例如远程桌面应用(如Windows Remote Desktop、VNC),允许用户通过网络远程访问和控制另一台计算机。这样用户可以在远程计算机上执行操作、获取文件等,就像直接在本地计算机上一样。
- 实时通信:网络编程允许实时通信,使得在不同计算机上的用户能够通过网络进行即时消息传递、语音通话、视频会议等。这对于远程协作、远程教学和远程支持等场景非常有用。例如FTP(文件传输协议)应用,允许用户通过网络在不同计算机之间传输文件。还有类似于云存储的应用(如Dropbox、Google Drive),允许用户通过网络将文件上传到服务器,并与他人共享。
- 资源共享:网络编程提供了一种方便的方式来共享计算机和服务器上的资源,例如共享文件、打印机、数据库等。通过网络,在不同的计算机之间可以共享和访问这些资源。例如分布式计算平台(如Hadoop、Spark),使用网络连接多台计算机,将任务分发给不同的计算节点并汇总结果。云计算平台(如Amazon Web Services、Microsoft Azure)也是一个例子,通过网络提供虚拟机、存储和其他服务供用户使用。
- 分布式计算和云服务:网络编程支持分布式计算和云服务。通过网络连接,计算机可以共同协作完成复杂的任务,并提供云计算平台和服务。例如Web应用程序(如在线购物网站、社交媒体平台)都是基于客户端-服务器模型的。
总而言之,网络编程的目的是利用计算机网络进行数据传输和通信,实现数据交换、远程访问、资源共享等功能。它使得不同计算机之间可以互相连接和通信,并充分利用网络的优势,提供更多的服务和可能性。
1.2 网络通信的要素
网络通信的要素包括以下几个方面:
-
协议(Protocol):协议是网络通信的基础,它规定了在网络上进行通信时所使用的规则和约定。常见的网络协议有TCP/IP、HTTP、FTP、SMTP等。不同的协议提供不同的功能和服务,如数据传输、文件共享、电子邮件发送等。
-
IP地址(IP Address):IP地址是用于标识和寻址网络上的设备的唯一标识符。它可以是IPv4地址(如192.168.0.1)或IPv6地址(如2001:0db8:85a3:0000:0000:8a2e:0370:7334)。通过IP地址,数据包可以正确地传递到目标设备。
-
端口(Port):端口是用于标识网络设备上不同应用程序或服务的标记。每个设备都有65536个端口号(从0到65535),其中一些端口号已经被保留用于特定的服务(如80端口用于HTTP)。通过指定源端口和目标端口,数据包可以被正确地路由到相应的应用程序。
-
Socket(套接字):Socket是在网络上进行通信时使用的编程接口。它允许应用程序通过发送和接收数据来进行网络通信。Socket提供了一组方法和函数,使得网络编程更加灵活和便捷。
-
数据包(Packet):数据包是网络通信中基本的数据单位。它包含了要发送的数据以及源地址和目标地址等信息。数据包可以通过网络传输到目标地址,然后在目标设备上重新组装成完整的数据。
-
带宽(Bandwidth):带宽指的是网络连接的传输容量,也可以理解为网络通信中的最大数据传输速率。带宽决定了网络上可以同时传输的数据量,直接影响数据传输的速度和效率。
1.3 IP
1.3.1 介绍
IP地址是标识互联网上设备(例如电脑、服务器、路由器等)的唯一数字标识符。它类似于我们现实生活中的门牌号,用于确保数据能够正确地从源设备传送到目标设备。IP地址由一系列数字组成,通常以点分十进制(例如,192.168.0.1)的形式表示。
-
IP地址分类
-
ipv4/ipv6
IPv4是较早且常用的版本,使用32位地址格式,约有40亿个可用地址。而IPv6是IPv4的后继版本,采用128位地址格式,具有极大的地址空间,能够处理未来互联网的需求。 -
公网/私网(互联网/局域网)
公网(Public Network)指的是通过互联网可公开访问的网络,它是全球范围内的互联网服务提供商(ISP)通过路由器和其他网络设备相互连接而形成的网络。公网是对所有用户开放的,任何人都可以使用公网进行通信、访问网站和互相传输数据。私网(Private Network)指的是在特定范围内建立的局域网(LAN)或广域网(WAN),其通信范围局限于组织、企业或家庭内部。私网通常是通过私人路由器、交换机和其他网络设备实现的,用于内部通信、共享资源和数据传输,与公网相隔离且不可公开访问。私网的一个重要特点是使用私有IP地址。私有IP地址是指为了在私网内部使用而保留的地址范围,不会在公网上路由。这些IP地址范围包括常见的10.0.0.0至10.255.255.255、172.16.0.0至172.31.255.255和192.168.0.0至192.168.255.255等。
私网与公网之间通常需要使用网络地址转换(NAT)或虚拟专用网络(VPN)等技术来实现连接和数据传输。私网提供了一种相对安全和受控的网络环境,有助于组织内部的资源共享和通信,同时保护了内部网络免受公网上的潜在威胁。
-
1.3.2 code
package com.ipText;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* ip观测
*
* @author pangyangjian
* @since 2023/9/5 20:16
*/
public class InetAddressExample {
public static void main(String[] args) {
try {
// 查询本机地址
InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
InetAddress inetAddress2 = InetAddress.getByName("localhost");
InetAddress inetAddress3 = InetAddress.getLocalHost();
// 查询网站ip地址
InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
System.out.println(inetAddress1);
System.out.println(inetAddress2);
System.out.println(inetAddress3);
System.out.println(inetAddress4);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
}
1.4 端口Port
端口(Port)是计算机网络中用于区分不同网络应用程序或服务的逻辑地址。在TCP/IP协议中,每个网络应用程序或服务都会占据一个唯一的端口号,用于在网络上传输数据。端口号是一个16位的数字,范围从0到65535。
端口号分为三个范围:
-
知名端口(Well-known Ports):范围从0到1023,预留给一些广泛使用的服务或协议,例如HTTP(端口号80)、HTTPS(端口号443)、FTP(端口号21)等。这些端口号在大多数操作系统中都有固定的分配。
-
注册端口(Registered Ports):范围从1024到49151,用于用户注册的应用程序或服务。这些端口号可以根据需要进行分配,但是应该避免与知名端口冲突。
-
动态/私有端口(Dynamic/Private Ports):范围从49152到65535,用于临时分配给客户端应用程序或动态选择的端口。
netstat -ano #查看所有端口 netstat -ano|findstr "abc" #查看指定的端口 tasklist|findstr “abc” #查看指定端口的进程
通过使用端口号,网络中的数据可以正确地被发送到目标应用程序或服务。发送方通过将源端口和目标端口与目标IP地址结合,组成一个唯一的网络套接字,确保数据能够正确地到达目标位置。例如,发送方的Web浏览器使用源端口号(通常是随机选择的高端动态端口)和目标IP地址的80端口(HTTP)来与Web服务器通信。
1.5 通信协议
通信协议(Communication Protocol)是为了确保在网络中的不同设备之间进行有效通信而制定的规则和约定。它定义了如何交换数据、建立连接、执行错误检测和纠正、数据传输的顺序以及其他与通信相关的操作。
通信协议通常由一系列规范和标准组成,确保在不同设备之间使用相同的规则来解释和处理数据。这些协议可以涉及物理层(如电缆类型和传输速率)、数据链路层(如MAC地址和帧格式)、网络层(如IP地址和路由选择)、传输层(如TCP和UDP)、应用层(如HTTP和FTP)等多个层次。
通信协议的定义包括以下几个方面:
-
语法(Syntax):定义了数据的格式和结构,包括数据的排列方式、标记和分隔符等。这确保了发送方和接收方对数据的解释是一致的。
-
语义(Semantics):定义了数据的含义和解释方式,包括字段的解释、通信流程的意义、操作的顺序等。这确保了数据能够以正确的方式被理解和处理。
-
时序(Timing):定义了数据的传输顺序和时间间隔,以及通信中各个操作的时序要求。这确保了数据在正确的时间被发送和接收,并且操作按照正确的顺序执行。
通信协议的定义使得不同厂商和不同类型的设备能够在网络中互相通信和协作,促进了信息的传递和共享。常见的通信协议包括TCP/IP、HTTP、FTP、SMTP、POP3等。
1.6 TCP/UDP
1.6.1 介绍
TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的网络传输协议。
TCP是一种面向连接的协议,它提供可靠的、有序的数据传输。TCP通过建立连接、数据分段、确认和重传机制来确保数据的可靠性和完整性。它适用于需要确保数据传输的应用程序,如文件传输、电子邮件和网页浏览。TCP通信是双向的,即通信双方都可以发送和接收数据。
UDP是一种无连接的协议,它提供不可靠的、面向数据报的数据传输。UDP将数据分割为数据报,并直接发送,不需要建立连接和确认,也不提供重传机制。UDP适用于要求实时性和效率的应用程序,如实时音视频传输、在线游戏和DNS查询。UDP通信是单向的,即只能由发送方发送数据,接收方接收数据。
它们的区别主要包括:
- 连接方式:TCP是面向连接的,而UDP是无连接的。
- 可靠性:TCP提供可靠的数据传输,通过确认和重传机制确保数据的完整性和正确性;而UDP不提供可靠性保证,发送的数据可能会丢失或乱序。
- 效率:TCP的可靠性机制会引入一定的延迟和额外的开销,因此相对而言,UDP具有更高的传输效率。
- 数据报大小:TCP允许发送的数据报大小没有限制,而UDP的数据报大小由协议本身的限制(约64KB)。
- 适用场景:TCP适用于要求可靠传输的应用,如文件传输和网页浏览;UDP适用于要求实时性和高效性的应用,如音视频传输和游戏。
需要根据具体的应用要求选择合适的协议进行数据传输。
1.6.2 代码
code 1 (TCP 实现聊天)
客户端
- 连接服务器Socket
- 发送消息
package com.tcpExample;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
* @author pangyangjian
* @since 2023/9/6 16:43
* c端模拟
*/
public class TcpClient {
public static void main(String[] args) {
try (Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
OutputStream os = socket.getOutputStream()) {
os.write("Hello world".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器
-
建立服务的端口ServerSocket
-
等待用户的链接accept
-
接收消息
package com.tcpExample;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* s端模拟
* @author pangyangjian
* @since 2023/9/7 11:55
*/
public class TcpServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(9999);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream()) {
byte[] buffer = new byte[1024];
int len;
StringBuilder stringBuilder = new StringBuilder();
while ((len = inputStream.read(buffer)) != -1) {
stringBuilder.append(new String(buffer, 0, len));
}
System.out.println(stringBuilder);
} catch (IOException e) {
e.printStackTrace();
}
}
}
code 2 (TCP 实现文件传输)
客户端
package com.tcpExample.fileTransfer;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
* TODO 类实现描述
*
* @author pangyangjian
* @since 2023/9/7 15:50
*/
public class TcpClient {
public static void main(String[] args) throws Exception {
// 1.创建一个socket链接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
// 2.创建一个输出流
OutputStream os = socket.getOutputStream();
// 3.读取文件
FileInputStream fis = new FileInputStream("42.jpg");
// 4.写文件
byte[] buffer = new byte[1024];
int len;
while((len= fis.read(buffer))!=-1){
os.write(buffer,0,len);
}
fis.close();
os.close();
socket.close();
}
}
服务端
package com.tcpExample.fileTransfer;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* TODO 类实现描述
*
* @author pangyangjian
* @since 2023/9/7 16:12
*/
public class TcpServer {
public static void main(String[] args) throws IOException {
// 1.创建服务
ServerSocket serverSocket = new ServerSocket(9090);
// 2.监听客户端的连接
Socket accept = serverSocket.accept();
// 3.获取输入流
InputStream is = accept.getInputStream();
// 4.文件输出
FileOutputStream fos = new FileOutputStream("receive.jpg");
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
// 5.关闭资源
fos.close();
is.close();
serverSocket.close();
}
}
code 3 (UDP 消息发送)
发送端
package com.udpExample.textTransmission;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* TODO 类实现描述
*
* @author pangyangjian
* @since 2023/9/7 18:19
*/
public class UDPSender {
public static void main(String[] args) throws Exception {
// 1.建立socket
DatagramSocket datagramSocket = new DatagramSocket();
// 2.建包
String msg = "hello";
InetAddress inetAddress = InetAddress.getByName("localhost");
int port = 9090;
DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, inetAddress, port);
// 3.发送包
datagramSocket.send(datagramPacket);
// 4. 关闭资源
datagramSocket.close();
}
}
接收端
package com.udpExample.textTransmission;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* TODO 类实现描述
*
* @author pangyangjian
* @since 2023/9/7 19:10
*/
public class UDPReceive {
public static void main(String[] args) throws IOException {
// 1.开放端口
DatagramSocket datagramSocket = new DatagramSocket(9090);
// 2.接收数据package
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
datagramSocket.receive(datagramPacket); // 阻塞接收
System.out.println(datagramPacket.getAddress() + " receive: " + new String(datagramPacket.getData(), 0,
datagramPacket.getLength()));
// 3.关闭连接
datagramSocket.close();
}
}
code 4 (UDP 模拟聊天)
发送端
package com.udpExample.chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
/**
* TODO sender
*
* @author pangyangjian
* @since 2023/9/7 20:02
*/
public class UDPSender {
public static void main(String[] args) throws Exception {
// 新建socket连接,定义端口为9090
DatagramSocket datagramSocket = new DatagramSocket(9090);
// 读取控制台输入的字符串
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
// 读取输入流中的一行文本
String s = bufferedReader.readLine();
byte[] bytes = s.getBytes();
// 打包数据
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress(
"localhost", 9191));
// 发送packet
datagramSocket.send(datagramPacket);
// 如果输入的时end,则停止循环
if ("end".equals(s)) {
break;
}
}
datagramSocket.close();
}
}
接收端
package com.udpExample.chat;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* TODO receiver
*
* @author pangyangjian
* @since 2023/9/7 20:02
*/
public class UDPReceive {
public static void main(String[] args) throws Exception {
// 创建连接,端口为9191
DatagramSocket datagramSocket = new DatagramSocket(9191);
while (true) {
byte[] bytes = new byte[1024];
// 创建datagramPacket对象
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
// 获取端口传出的数据并赋值datagramPacket
datagramSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
String s = new String(data);
System.out.println(datagramPacket.getAddress() + " " + s.trim());
if ("end".equals(s)) {
break;
}
}
datagramSocket.close();
}
}
code 5 (UDP 多线程在线咨询)
Sender
package com.udpExample.consultingSimulation;
/**
* sender 发送端
*
* @author pangyangjian
* @since 2023/9/11 17:30
*/
public class Sender {
public static void main(String[] args) {
new Thread(new TalkSendThread(7777,"localhost",8888)).start();
new Thread(new TalkReceiveThread(9999,"Consultant")).start();
}
}
Receiver
package com.udpExample.consultingSimulation;
/**
* receiver 接收端
*
* @author pangyangjian
* @since 2023/9/11 17:30
*/
public class Receiver {
public static void main(String[] args) {
new Thread(new TalkSendThread(6666, "localhost", 9999)).start();
new Thread(new TalkReceiveThread(8888,"customer")).start();
}
}
线程-发送
package com.udpExample.consultingSimulation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
/**
* Thread-send
* @author pangyangjian
* @since 2023/9/11 15:50
*/
public class TalkSendThread implements Runnable {
DatagramSocket datagramSocket;
BufferedReader bufferedReader;
private final String toIp;
private final int toPort;
public TalkSendThread(int fromPort, String toIp, int toPort) {
this.toIp = toIp;
this.toPort = toPort;
try {
datagramSocket = new DatagramSocket(fromPort);
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
@Override
public void run() {
while (true) {
// 读取输入流中的一行文本
String s;
try {
s = bufferedReader.readLine();
byte[] bytes = s.getBytes();
// 打包数据
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress(
toIp, toPort));
// 发送packet
datagramSocket.send(datagramPacket);
// 如果输入的时end,则停止循环
if ("end".equals(s)) {
break;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
线程-接收
package com.udpExample.consultingSimulation;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* Thread-receive
* @author pangyangjian
* @since 2023/9/11 17:16
*/
public class TalkReceiveThread implements Runnable {
DatagramSocket datagramSocket;
private final String msgFrom;
public TalkReceiveThread(int port, String msgFrom) {
this.msgFrom = msgFrom;
try {
datagramSocket = new DatagramSocket(port);
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
@Override
public void run() {
while (true) {
try {
byte[] bytes = new byte[1024];
// 创建datagramPacket对象
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
// 获取端口传出的数据并赋值datagramPacket
datagramSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
String s = new String(data);
System.out.println(msgFrom + " : " + s.trim());
if ("end".equals(s)) {
break;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
1.7 Tomcate
Tomcat是一个开源的Java Servlet容器,由Apache软件基金会开发和维护。它是一个服务器,用于执行Java Servlet、JavaServer Pages(JSP)和相关技术的Web应用程序。
Tomcat是基于Java语言的,它提供了一种简单且轻量级的方式来运行和托管Java Web应用程序。它支持HTTP协议,可以通过网络接收请求并相应地处理它们。Tomcat还支持其他一些重要的网络协议,如HTTPS、WebSocket等。
Tomcat还提供了许多功能,例如连接池管理、会话管理、安全管理、日志记录等。它可以与其他常见的Java EE(Enterprise Edition)技术和框架集成,如Spring、Hibernate等。
Tomcat的架构使得它易于安装、配置和部署。它可以作为独立的Web服务器运行,也可以与Apache HTTP服务器等其他Web服务器进行集成使用。
总的来说,Tomcat是一个流行且功能强大的Servlet容器,被广泛用于开发、测试和运行Java Web应用程序。
Tomcat安装步骤及详细配置教程(2022最新版)_tomcat安装及配置教程
1.8 URL
1.8.1 介绍
URL是统一资源定位符(Uniform Resource Locator)的缩写,它是用于标识和定位互联网上资源的地址。URL由多个部分组成,包括协议、主机、端口、路径和查询参数等。
下面是URL的一般格式:
protocol://host:port/path?query
- 协议(protocol)指定了用于访问资源的协议,常见的协议有HTTP、HTTPS、FTP等。
- 主机(host)指定了资源所在的主机名或IP地址。
- 端口(port)指定了与主机通信的端口号,用于区分不同的网络服务,默认情况下,HTTP使用80端口,HTTPS使用443端口。
- 路径(path)指示了资源在服务器上的位置,包括目录和文件名。
- 查询参数(query)是可选的,用于向服务器传递附加的参数和数据,通常以键值对的形式出现,多个参数之间使用
&分隔。
以下是一些示例URL:
- https://www.example.com/index.html
- ftp://ftp.example.com/downloads/file.zip
- http://localhost:8080/myapp/page.jsp?id=123&name=John
通过URL可以在浏览器中访问和定位不同网页、文件和其他网络资源。URL是互联网上资源的唯一标识。
1.8.2 code
package com.udpExample.networkResourceDownload;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 下载网络资源
*
* @author pangyangjian
* @since 2023/9/12 13:46
*/
public class Url {
public static void main(String[] args) throws IOException {
// get download url
final URL url = new URL("https://i0.hdslb.com/bfs/face/2b46429e928ea552f5d816a824f5b2dc7b129cdd" +
".jpg@160w_160h_1c_1s_!web-avatar-comment.webp");
// connect to this url
final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// get stream
final InputStream inputStream = urlConnection.getInputStream();
final FileOutputStream fileOutputStream = new FileOutputStream("download Result.jpg");
final byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes,0,len);
}
fileOutputStream.close();
inputStream.close();
urlConnection.disconnect();
}
}

浙公网安备 33010602011771号