# 网络编程: ## 软件架构: **BS** Browser Server 浏览器 服务端 **CS** Client Server 客户段 服务端 ## 总结: image-20251229162046866 ## 网络编程三要素 ### **IP** image-20251229162723116 **特殊ip地址:** ![image-20251229163018519](https://gitee.com/icecat2233/picture/raw/master/20251229163019681.png) **常用命令:** ipconfig:查看本机ip地址 ping:检查网络是否畅通 ### **端口** image-20251229164022824 ### 协议 **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协议:可靠信息安全,速度慢** image-20251229173457548 **三次握手:** image-20251229184654252 **四次挥手:** image-20251229185454457 大型案例:重点分析: 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()来生成随机名字