- 网络编程(含 UrlConnection 发送 HTTP 请求下载文件):https://blog.csdn.net/qq_41538097/article/details/118722718
- Apache HttpComponents 简单使用:https://blog.csdn.net/qq_41538097/article/details/123719298
- RestTemplate简单使用:https://blog.csdn.net/qq_41538097/article/details/123560238
- okhttp3简单使用:https://blog.csdn.net/qq_41538097/article/details/123677614
- HttpURLConnection 简单使用:https://blog.csdn.net/qq_41538097/article/details/123697432
一、网络模型
二、获取 IP
通过 InetAddress 类获取 IPv4 地址
InetAddress localhost = InetAddress.getByName("localhost");
System.out.println(localhost); // localhost/127.0.0.1
System.out.println(InetAddress.getLocalHost()); // LingyueYe/192.168.3.185
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost.getHostAddress()); // 192.168.3.185
System.out.println(localHost.getHostName()); // LingyueYe
如果你有多个网卡可以获取全部的 IPv4 地址
private static List<String> getIpAddress() throws SocketException {
List<String> list = new LinkedList<>();
Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
while (enumeration.hasMoreElements()) {
NetworkInterface network = enumeration.nextElement();
Enumeration<InetAddress> addresses = network.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress address = addresses.nextElement();
if (address instanceof Inet4Address) {
list.add(address.getHostAddress());
}
}
}
return list;
}
# 我电脑装了虚拟机有四个 IP 地址
list:[127.0.0.1, 192.168.159.1, 192.168.1.1, 192.168.3.240]
三、TCP 协议
1、建立连接
- 建立服务端监听客户端连接,一定要手动关闭连接,否则 java 自动关闭连接会报错
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9997);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while((len=inputStream.read(bytes))!=-1){
byteArrayOutputStream.write(bytes,0,len);
}
System.out.println(new String(bytes));
byteArrayOutputStream.close();
inputStream.close();
accept.close();
serverSocket.close();
}
- 建立客户端连接服务端,一定要手动关闭连接,否则 java 自动关闭连接会报错
public static void main(String[] args) throws IOException {
InetAddress localhost = InetAddress.getByName("1.117.165.107");
int port = 9997;
System.out.println(localhost.getHostAddress());
Socket socket = new Socket(localhost.getHostAddress(), port);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("学习网络编程".getBytes());
outputStream.close();
socket.close();
}
连接成功
2、上传文件
- 客户端
public static void main(String[] args) throws IOException {
System.out.println("请输入上传的的文件名路径");
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
Socket socket = new Socket("1.117.165.107", 9997);//
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = new FileInputStream(new File("src/main/java/com/ye/"+next));
byte[] bytes = new byte[20];
int len;
while((len=inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,len); off 偏移量,偏移量0 代表紧跟追加,将 bytes.length 的字节写入文件(追加的形式)
}
// 通知服务器,我已经写入完毕
socket.shutdownInput();
// 判断是否写入完毕
socket.isInputShutdown();
socket.shutdownInput();
socket.isOutputShutdown();
socket.isConnected();
socket.isClosed();
inputStream.close();
outputStream.close();
socket.close();
}
- 服务端
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9997);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
String fileName = UUID.randomUUID().toString().replace("-", "")+".txt";
OutputStream outputStream = new FileOutputStream(new File(fileName));
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
outputStream.close();
inputStream.close();
accept.close();
serverSocket.close();
}
- 运行结果
四、UDP 协议
无状态协议
- 客户端
public static void main(String[] args) throws IOException {
// 使用 connect() 连接远程地址,数据包只能发送到或从该地址接收。
// 建立一个 socket,该客户端端口号 9998
DatagramSocket datagramSocket = new DatagramSocket(9998);
String str = "你好呀!UDP";
// 连接 9997 客户端,将包裹发送到指定 9997 端口
datagramSocket.connect(InetAddress.getByName("127.0.0.1"), 9997);
// 需要发送的数据
DatagramPacket datagramPacket = new DatagramPacket(str.getBytes(), 0, str.getBytes().length);
datagramSocket.send(datagramPacket);
datagramSocket.close();
// DatagramPacket 指定数据包发的地址
DatagramSocket datagramSocket2 = new DatagramSocket();
String str2 = "你好呀!UDP2";
// 需要发送的数据
DatagramPacket datagramPacket2 = new DatagramPacket(str2.getBytes(), 0, str2.getBytes().length, InetAddress.getByName("127.0.0.1"), 9997);
datagramSocket2.send(datagramPacket2);
datagramSocket2.close();
}
- 服务端
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(9997);
// 准备接收包裹
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length);
while (true) {
datagramSocket.receive(datagramPacket); // 阻塞接收
System.out.println(datagramPacket.getAddress());
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
}
}
- 测试连接
五、下载网络资源
使用 URLConnection 下载 网易云歌曲
public static void main(String[] args) throws IOException {
URL url = new URL("https://m701.music.126.net/20210715112506/36079aa66fa5d52682401a9ad2a02e4f/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/9836255744/326a/aad9/2c3a/a1257b6740eed2f70dc115a5ed3be1b4.m4a");
URLConnection urlConnection = url.openConnection();
// 如果报 Server returned HTTP response code: 403 for URL 可添加如下
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36");
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(new File("123456.m4a"));
byte[] bytes = new byte[1024];
int len;
while((len=inputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}
fileOutputStream.close();
inputStream.close();
}