Files
Java-Basic-and-Advanced/网络编程.md
2026-01-07 16:14:38 +08:00

238 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 网络编程:
## 软件架构:
**BS**
Browser Server 浏览器 服务端
**CS**
Client Server 客户段 服务端
## 总结:
<img src="https://gitee.com/icecat2233/picture/raw/master/20251229162054898.png" alt="image-20251229162046866" style="zoom: 50%;" />
## 网络编程三要素
### **IP**
<img src="https://gitee.com/icecat2233/picture/raw/master/20251229162724636.png" alt="image-20251229162723116" style="zoom:50%;" />
**特殊ip地址**
![image-20251229163018519](https://gitee.com/icecat2233/picture/raw/master/20251229163019681.png)
**常用命令:**
ipconfig:查看本机ip地址
ping:检查网络是否畅通
### **端口**
<img src="https://gitee.com/icecat2233/picture/raw/master/20251229164024494.png" alt="image-20251229164022824" style="zoom:50%;" />
### 协议
**UDP协议不可靠 速度快**
案例:收发消息:
接收端:
```Java
public class Receive {
public static void main(String[] args) throws Exception{
//创建DatagramSocket对象
DatagramSocket socket = new DatagramSocket(9999);
//创建DatagramPacket对象
DatagramPacket packet = new DatagramPacket(new byte[1024],1024);
//接受信息
socket.receive(packet);
//拆包裹
byte [] data =packet.getData();
String msg = new String(data);
String ip = packet.getAddress().getHostAddress();
System.out.println(""+ip+"ip发过来的信息"+msg);
//释放资源
socket.close();
}
}
```
发送端:
```Java
public class Send {
public static void main(String[] args) throws Exception{
//创建DatagramSocket对象
DatagramSocket socket = new DatagramSocket(8888);
//准备材料
String msg ="あんな别吃了";
byte[] bytes = msg.getBytes();
//打包包裹
DatagramPacket packet = new DatagramPacket(bytes,
bytes.length,
InetAddress.getByName("127.0.0.1"),//参数为对方的ip对方的端口
9999);
socket.send(packet);
socket.close();
}
}
```
**TCP协议可靠信息安全速度慢**
<img src="https://gitee.com/icecat2233/picture/raw/master/20251229173459039.png" alt="image-20251229173457548" style="zoom:50%;" />
**三次握手:**
<img src="https://gitee.com/icecat2233/picture/raw/master/20251229184655532.png" alt="image-20251229184654252" style="zoom: 50%;" />
**四次挥手:**
<img src="https://gitee.com/icecat2233/picture/raw/master/20251229185455707.png" alt="image-20251229185454457" style="zoom:50%;" />
大型案例:重点分析:
TCP上传文件
客户端
```Java
package com.ice.cat.test;
import java.io.*;
import java.lang.reflect.Type;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("10.104.117.228",9999);
//获取输入输出流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//将字节流转化为字符流,用来处理一些中文字符,再转化为字符缓冲流,可以读取一整行
BufferedReader br = new BufferedReader(new InputStreamReader(is));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//写出文件的名字
File file = new File("C:\\Users\\asus\\Pictures\\ariya.png");
bw.write(file.getName());//没带换行符
bw.newLine();
bw.flush();
//接受客户端反馈
String flag = br.readLine();
if (flag.equals("ok")){
//继续上传文件
//创建本地流,上传图片
FileInputStream fle = new FileInputStream(file);
byte [] bys = new byte[1024];
int lne;
while ((lne = fle.read(bys)) != -1){
os.write(bys,0,lne);
}
fle.close();
//重点:给服务端一个结束标记
socket.shutdownOutput();//通俗理解,写出了一个-1标记
}
//读取服务端的返回消息消息
String result = br.readLine();
System.out.println(result);
socket.close();
}
}
```
服务端:
```Java
package com.ice.cat.test;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
import java.util.concurrent.*;
public class Server {
public static void main(String[] args) throws Exception {
//创建线程池
ThreadPoolExecutor pool = new ThreadPoolExecutor(4,
6,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
ServerSocket server = new ServerSocket(9999);
System.out.println("服务端开启,等待客户端连接");
//响应请求
//多次响应上传图片,用循环包裹
while (true) {
Socket socket = server.accept();
pool.submit(new SubmitTask(socket));
}
}
}
```
线程池代码:为实现多次运行,可在不同线程进行调用
```Java
package com.ice.cat.test;
import java.io.*;
import java.net.Socket;
import java.util.UUID;
public class SubmitTask implements Runnable{
private Socket socket;
public SubmitTask(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//将字节流转化为字符流,用来处理一些中文字符,再转化为字符缓冲流,可以读取一整行
BufferedReader br = new BufferedReader(new InputStreamReader(is));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//接受文件名字
String resultName = br.readLine();
//给用户端反馈
bw.write("ok");
bw.newLine();
bw.flush();
//读取客户端上传的文件,注意写出上传的位置
//为避免文件名字重复使用UUID方法
File file = new File("C:\\Users\\asus\\Desktop\\JAVA", UUID.randomUUID().toString() + resultName);
//准备本地的输出流,将网络服务端数据写入到指定位置
FileOutputStream fos = new FileOutputStream(file);
//读取网络流数据,写入到本地文件
int lne;
byte[] bys = new byte[1024];
//is为网络输入流没有关联文件不可能有-1
while ((lne = is.read(bys)) != -1) {
fos.write(bys, 0, lne);
}
fos.close();
//回写给客户段消息
bw.write("上传成功");
bw.newLine();
bw.flush();
//关流
socket.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
```
补充点若文件名重复则使用UUID.randomUUID().toString()来生成随机名字