• 网络编程实战(二)


    目录

    一、TCP文件上传实现

    二、UDP消息发送

    2.1 DatagramPacket

    2.2 DatagramSocket

    2.3 实现消息通信

    三、UDP聊天实现

    四、UDP多线程在线咨询

    五、URL下载网络资源

    一、TCP文件上传实现

    准备工作:准备一张图片放于根目录下

    客户端:1)创建一个socket连接

                   2)创建一个输出流

                   3)需要拿到文件 --->  需要文件流

                   4)将文件写出 (需要用到IO流知识点,这一块都是固定写法)

                   5)通知服务器传输完毕

                   6)确认服务器接收完毕,断开连接

                   7)关闭资源

    1. import java.io.ByteArrayOutputStream;
    2. import java.io.FileInputStream;
    3. import java.io.InputStream;
    4. import java.io.OutputStream;
    5. import java.net.InetAddress;
    6. import java.net.Socket;
    7. public class TcpClientDemo02 {
    8. public static void main(String[] args) throws Exception {
    9. //1.创建一个socket连接
    10. Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
    11. //2.创建一个输出流
    12. OutputStream os = socket.getOutputStream();
    13. //3.文件流(拿到文件)
    14. FileInputStream fis = new FileInputStream("tx.PNG");
    15. //4.写出文件
    16. byte[] buffer = new byte[1024];//缓冲区
    17. int len;
    18. while((len=fis.read(buffer))!=-1){
    19. os.write(buffer,0,len);
    20. }
    21. //通知服务器传输完毕
    22. socket.shutdownOutput();
    23. //确定服务器接收完毕,才断开连接
    24. InputStream inputStream = socket.getInputStream();
    25. ByteArrayOutputStream baos = new ByteArrayOutputStream();
    26. byte[] buffer2 = new byte[2014];
    27. int len2;
    28. while((len2=inputStream.read(buffer2))!=-1){
    29. baos.write(buffer2,0,len2);
    30. }
    31. System.out.println(baos.toString());
    32. //关闭资源
    33. baos.close();
    34. inputStream.close();
    35. fis.close();
    36. os.close();
    37. socket.close();
    38. }
    39. }

    服务器:1)创建服务 (两边端口号需一致)

                   2)监听客户端的连接

                   3)获取输入流

                   4)文件输出 ---> 利用管道输出流 (固定写法)

                   5)通知客户端接收完毕

                   6)关闭资源

    1. import java.io.File;
    2. import java.io.FileOutputStream;
    3. import java.io.InputStream;
    4. import java.io.OutputStream;
    5. import java.net.ServerSocket;
    6. import java.net.Socket;
    7. public class TcpServerDemo02 {
    8. public static void main(String[] args) throws Exception {
    9. //1.创建服务
    10. ServerSocket serverSocket = new ServerSocket(9000);
    11. //2.监听客户端的连接
    12. Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端的连接
    13. //3.获取输入流
    14. InputStream is = socket.getInputStream();
    15. //4.文件输出(利用管道输出流)
    16. FileOutputStream fos = new FileOutputStream(new File("receive.PNG"));
    17. byte[] buffer = new byte[1024];
    18. int len;
    19. while((len=is.read(buffer))!=-1){
    20. fos.write(buffer,0,len);
    21. }
    22. //通知客户端接收完毕
    23. OutputStream os = socket.getOutputStream();
    24. os.write("可以断开了".getBytes());
    25. //5.关闭资源
    26. fos.close();
    27. is.close();
    28. socket.close();
    29. serverSocket.close();
    30. }
    31. }

    运行结果:

    tx.PNG是事先准备的资源文件         receive.PNG是接收到的资源文件

    二、UDP消息发送

    2.1 DatagramPacket

    在码头发送和接收货物时都需要使用集装箱来装载货物,UDP通信也是一样,发送和接收的数据也需要使用“集装箱”进行打包,为此JDK中提供了一个DatagramPacket类,该类的实例对象就相当于一个集装箱,用于封装UDP通信中发送或者接收的数据。

    2.2 DatagramSocket

    DatagramPacket数据包的作用就如同是“集装箱”,可以将发送端或者接收端的数据封装起来。然而运输货物只有“集装箱”是不够的,还需要有码头。在程序中需要实现通信只有DatagramPacket数据包也同样不行,为此JDK中提供的一个DatagramSocket类。DatagramSocket类的作用就类似于码头,使用这个类的实例对象就可以发送和接收DatagramPacket数据包,发送数据的过程如下图所示。

    2.3 实现消息通信

    实际UDP通信中并不存在客服端和服务器一说法

    发送端:  1)需要一个socket

                     2)建个包

                     3)确定发送对象

                     4)发送包

                     5)关闭流

    1. import java.net.DatagramPacket;
    2. import java.net.DatagramSocket;
    3. import java.net.InetAddress;
    4. //不需要连接服务器
    5. public class UDPClientDemo01 {
    6. public static void main(String[] args) throws Exception {
    7. //1.建立一个socket
    8. DatagramSocket socket = new DatagramSocket();
    9. //2.建个包
    10. String msg="hello";
    11. //发送给谁
    12. InetAddress localhost = InetAddress.getByName("localhost");
    13. int port=9090;
    14. //getBytes() 是Java编程语言中将一个字符串转化为一个字节数组byte[]的方法
    15. //参数:数据 数据的长度 发送给谁
    16. DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
    17. //3.发送包
    18. socket.send(packet);
    19. //4.关闭流
    20. socket.close();
    21. }
    22. }

    接收端: 1)开放端口

                   2)接收数据包

                   3)读取内容

                   4)关闭流

    1. //需要等待客户端的连接
    2. public class UDPServerDemo01 {
    3. public static void main(String[] args) throws Exception {
    4. //开放端口
    5. DatagramSocket socket = new DatagramSocket(9090);
    6. //接收数据包
    7. byte[] buffer = new byte[1024];
    8. DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);//接收
    9. socket.receive(packet);//阻塞接受
    10. //读取内容
    11. System.out.println(packet.getAddress().getHostAddress());
    12. System.out.println(new String(packet.getData(),0,packet.getLength()));
    13. //关闭流
    14. socket.close();
    15. }
    16. }

    运行结果:

    三、UDP聊天实现

    发送方:

    1. import java.io.BufferedReader;
    2. import java.io.InputStreamReader;
    3. import java.net.DatagramPacket;
    4. import java.net.DatagramSocket;
    5. import java.net.InetSocketAddress;
    6. public class UDPSendDemo01 {
    7. public static void main(String[] args) throws Exception {
    8. DatagramSocket socket = new DatagramSocket(8888);
    9. //准备数据:控制台读取 System.in
    10. BufferedReader reader= new BufferedReader(new InputStreamReader(System.in));
    11. while (true){
    12. String data= reader.readLine();
    13. byte[] datas=data.getBytes();
    14. DatagramPacket packet=new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
    15. socket.send(packet);
    16. if (data.equals("bye")){
    17. break;
    18. }
    19. }
    20. socket.close();
    21. }
    22. }

    接收方:

    1. import java.net.DatagramPacket;
    2. import java.net.DatagramSocket;
    3. public class UDPReceiveDemo01 {
    4. public static void main(String[] args) throws Exception {
    5. DatagramSocket socket = new DatagramSocket(6666);
    6. //循环接收
    7. while (true){
    8. //准备接收包裹
    9. byte[] container = new byte[1024];
    10. DatagramPacket packet = new DatagramPacket(container,0,container.length);
    11. socket.receive(packet);//阻塞式接收包裹
    12. //断开连接
    13. byte[] data=packet.getData();
    14. String receiveData = new String(data, 0, packet.getLength());
    15. System.out.println(receiveData);
    16. if(receiveData.equals("bye")) {
    17. break;
    18. }
    19. }
    20. socket.close();
    21. }
    22. }

    运行结果:

    四、UDP多线程在线咨询

    双方互为发送方与接收方

    案例:模拟教师-学生间互发消息

    发送端:

    1. import java.io.BufferedReader;
    2. import java.io.IOException;
    3. import java.io.InputStreamReader;
    4. import java.net.DatagramPacket;
    5. import java.net.DatagramSocket;
    6. import java.net.InetSocketAddress;
    7. import java.net.SocketException;
    8. public class TalkSend implements Runnable{
    9. private int fromPort;
    10. private String toIP;
    11. private int toPort;
    12. DatagramSocket socket = null;
    13. BufferedReader reader = null;
    14. public TalkSend(int fromPort, String toIP,int toPort) {
    15. this.fromPort = fromPort;
    16. this.toIP = toIP;
    17. this.toPort = toPort;
    18. try {
    19. //初始化建立连接
    20. socket = new DatagramSocket(fromPort);
    21. //控制台获取输入的文字信息
    22. reader = new BufferedReader(new InputStreamReader(System.in));
    23. } catch (SocketException e) {
    24. e.printStackTrace();
    25. }
    26. }
    27. @Override
    28. public void run() {
    29. while(true){
    30. try {
    31. //读取数据
    32. String data = reader.readLine();
    33. //新建数据包
    34. byte[] datas = data.getBytes();
    35. DatagramPacket packet = new DatagramPacket (datas, 0, datas.length,new InetSocketAddress(this.toIP,this.toPort));
    36. //发送包
    37. socket.send(packet);
    38. if(data.startsWith("bye"))
    39. break;
    40. } catch (IOException e) {
    41. e.printStackTrace();
    42. }
    43. }
    44. }
    45. }

    接收端:

    1. import java.net.DatagramPacket;
    2. import java.net.DatagramSocket;
    3. public class TalkReceive implements Runnable{
    4. DatagramSocket socket = null;
    5. private int port;
    6. private String msgFrom;
    7. public TalkReceive(int port, String msgFrom) {
    8. this.port = port;
    9. this.msgFrom = msgFrom;
    10. try {
    11. //初始化建立连接
    12. socket = new DatagramSocket(port);
    13. } catch (Exception e) {
    14. e.printStackTrace();
    15. }
    16. }
    17. @Override
    18. public void run() {
    19. //无限循环获取消息
    20. while (true){
    21. try {
    22. byte[] container = new byte[1024];
    23. //新建包用于存储等下要接收的信息
    24. DatagramPacket packet = new DatagramPacket(container, 0, container.length);
    25. //存储到packet里面
    26. socket.receive(packet);
    27. //转换
    28. byte[] data = packet.getData();
    29. String receiveData = new String(data, 0, packet.getLength());
    30. System.out.println(msgFrom + ":" + receiveData);
    31. if(receiveData.startsWith("bye")){
    32. break;
    33. }
    34. } catch (Exception e) {
    35. e.printStackTrace();
    36. }
    37. }
    38. socket.close();
    39. }
    40. }

    学生:

    1. public class TalkStudent{
    2. public static void main(String[] args) {
    3. //开启两个线程
    4. new Thread(new TalkSend(7777,"localhost",9999)).start();
    5. new Thread(new TalkReceive(8888,"老师")).start();
    6. }
    7. }

    老师:

    1. public class TalkTeacher {
    2. public static void main(String[] args) {
    3. new Thread(new TalkSend(5555,"localhost",8888)).start();
    4. new Thread(new TalkReceive(9999,"学生")).start();
    5. }
    6. }

    运行结果:

    学生收到的信息:

    老师收到的信息:

    五、URL下载网络资源

    URL:统一资源定位符,定位资源,即定位互联网上的某一个资源

    DNS:域名解析

    案例:测试URL

    1. import java.net.MalformedURLException;
    2. import java.net.URL;
    3. public class URLDemo01 {
    4. public static void main(String[] args) throws MalformedURLException {
    5. URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=biubiu$password=123");
    6. System.out.println(url.getProtocol());//协议名
    7. System.out.println(url.getHost());//主机(IP)
    8. System.out.println(url.getPort());//端口号
    9. System.out.println(url.getPath());//文件地址
    10. System.out.println(url.getFile());//文件全路径
    11. System.out.println(url.getQuery());//参数
    12. }
    13. }

    案例:下载网络资源,这里以下载图片为例

    1. import java.io.FileOutputStream;
    2. import java.io.InputStream;
    3. import java.net.HttpURLConnection;
    4. import java.net.URL;
    5. public class urlDown {
    6. public static void main(String[] args) throws Exception {
    7. //1.下载地址
    8. URL url = new URL("https://img-blog.csdnimg.cn/018fc854848e4a92b9b4e2db976aa779.png");
    9. //2。连接到这个地址
    10. HttpURLConnection urlConnection=(HttpURLConnection) url.openConnection();
    11. InputStream inputStream = urlConnection.getInputStream();
    12. FileOutputStream fos = new FileOutputStream("test.png");
    13. byte[] buffer = new byte[1024];
    14. int len;
    15. while((len=inputStream.read(buffer))!=-1){
    16. fos.write(buffer,0,len);
    17. }
    18. fos.close();
    19. inputStream.close();
    20. urlConnection.disconnect();
    21. }
    22. }

    运行结果:图片被成功下载

  • 相关阅读:
    docker部署Vaultwarden密码共享管理系统
    redis面试基础
    vue生成动态表单
    大数据之LibrA数据库系统告警处理(ALM-12030 无合法license存在)
    【字符串】【字符串和字符数组的相互转化】Leetcode 541 反转字符串 II
    Vue3中组件数据的传递以及更改
    EFDC模型教程
    请问swat输出的是有机氮、 有机磷、 硝态氮等,但目前只有总磷、总氮和氨氮的数据,该怎么率定呢?
    linux安装Jdk
    OBS-Studio-27.2.4-Full-Installer-x64.exe 下载
  • 原文地址:https://blog.csdn.net/qq_61727355/article/details/126166307