238 lines
7.0 KiB
Markdown
238 lines
7.0 KiB
Markdown
# 网络编程:
|
||
|
||
## 软件架构:
|
||
|
||
**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地址:**
|
||
|
||

|
||
|
||
**常用命令:**
|
||
|
||
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()来生成随机名字 |