TCP与UDP网络编程

news2024/9/23 15:27:56

网络通信协议

在这里插入图片描述

java.net 包中提供了两种常见的网络协议的支持:

  • UDP:用户数据报协议(User Datagram Protocol)
  • TCP:传输控制协议(Transmission Control Protocol)

TCP协议与UDP协议

TCP协议

  • TCP协议进行通信的两个应用进程:客户端、服务端
  • 使用TCP协议前,须先建立TCP连接,形成基于字节流的传输数据通道
  • 传输前,采用“三次握手”方式,点对点通信,是可靠
    • TCP协议使用重发机制,当一个通信实体发送一个消息给另一个通信实体后,需要收到另一个通信实体确认信息,如果没有收到另一个通信实体确认信息,则会再次重复刚才发送的消息
  • 在连接中可进行大数据量的传输
    传输完毕,需释放已建立的连接,效率低

UDP协议

  • UDP协议进行通信的两个应用进程:发送端、接收端
  • 将数据、源、目的封装成数据包(传输的基本单位),不需要建立连接
  • 发送不管对方是否准备好,接收方收到也不确认,不能保证数据的完整性,故是不可靠
  • 每个数据报的大小限制在64K
  • 发送数据结束时无需释放资源,开销小,通信效率高
  • 适用场景:音频、视频和普通数据的传输。例如视频会议

生活案例

TCP生活案例:打电话

UDP生活案例:发送短信、发电报

TCP协议

三次握手

在这里插入图片描述

四次挥手

在这里插入图片描述

网络编程API

Socket类

基本介绍

在这里插入图片描述

在这里插入图片描述

示意图:

在这里插入图片描述

理解客户端、服务端

  • 客户端:

    • 自定义
    • 浏览器(browser — server)
  • 服务端:

    • 自定义
    • Tomcat服务器

TCP网络编程

通信模型

在这里插入图片描述

例题1

客户端发送内容给服务端,服务端将内容打印到控制台上。

public class TCPTest1 {

    //客户端
    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;

        try {
            // 1.创建一个Socket
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1"); //声明ip地址
            int port = 8989; //声明端口号
            socket = new Socket(inetAddress,port);

            // 2.发送数据
            os = socket.getOutputStream();
            os.write("你好,我是客户端,请多多关照".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 3.关闭socket、流
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (os != null)
                    os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //服务端
    @Test
    public void server() {
        ServerSocket serverSocket = null;
        Socket socket = null; //阻塞式方法
        InputStream is = null;
        try {
            // 1.创建一个ServerSocket
            int port = 8989;
            serverSocket = new ServerSocket(port);

            // 2.调用accept(),接收客户端的Socket
            socket = serverSocket.accept();
            System.out.println("服务器端已开启");

            System.out.println("收到了来自于" + socket.getInetAddress().getHostAddress() + "的连接");

            // 3.接收数据
            is = socket.getInputStream();
            byte[] buffer = new byte[1024];
            ByteArrayOutputStream baos = new ByteArrayOutputStream(); //内部维护了一个byte[]
            int len;
            while ((len = is.read(buffer)) != -1) {
                // 错误的,可能会出现乱码
//                String str = new String(buffer,0,len);
//                System.out.println(str);

                //正确的
                baos.write(buffer,0,len);
            }

            System.out.println(baos.toString());

            System.out.println("\n数据接收完毕");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.关朗Socket、ServerSocket、流
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

例题2

客户端发送文件给服务端,服务端将文件保存在本地。

public class TCPTest2 {
    //客户端
    @Test
    public void client() {
        // 1.创建Socket
        // 指明对方(即为服务器)的ip地址和端口号
        Socket socket = null;
        FileInputStream fis = null;
        OutputStream os = null;
        try {
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
            int port = 9090;
            socket = new Socket(inetAddress,port);

            // 2.创建File的实例、FileInputstream的实例
            File file = new File("huan.jpg");
            fis = new FileInputStream(file);

            // 3.通过Socket,获取输出流
            os = socket.getOutputStream();

            // 读写数据
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                os.write(buffer,0,len);
            }
            System.out.println("数据发送完毕");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4.关闭Socket和相关的流
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //服务端
    @Test
    public void server() {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            // 1.创建ServerSocket
            int port = 9090;
            serverSocket = new ServerSocket(port);

            // 2.接收来自于客户端的socket:accept()
            socket = serverSocket.accept();

            // 3.通过Socket获取一个输入流
            is = socket.getInputStream();

            // 4.创建File类的实例、File0utputstream的实例
            File file = new File("huan_copy.jpg");
            fos = new FileOutputStream(file);

            // 5.读写过程
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer,0,len);
            }

            System.out.println("数据接收完毕");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 6.关闭相关的Socket和流
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

例题3

从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功"给客户端。并关闭相应的连接。

public class TCPTest3 {
    //客户端
    @Test
    public void client() {
        // 1.创建Socket
        // 指明对方(即为服务器)的ip地址和端口号
        Socket socket = null;
        FileInputStream fis = null;
        OutputStream os = null;
        ByteArrayOutputStream baos = null;
        InputStream is = null;
        try {
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
            int port = 9090;
            socket = new Socket(inetAddress, port);

            // 2.创建File的实例、FileInputstream的实例
            File file = new File("huan.jpg");
            fis = new FileInputStream(file);

            // 3.通过Socket,获取输出流
            os = socket.getOutputStream();

            // 4.读写数据
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            System.out.println("数据发送完毕");

            // 5.客户端表明不再继续发送数据
            socket.shutdownOutput();

            // 6.接收来自于服务器端的数据
            is = socket.getInputStream();
            baos = new ByteArrayOutputStream();
            byte[] buffer1 = new byte[5];
            int len1;
            while ((len1 = is.read(buffer1)) != -1) {
                baos.write(buffer1, 0, len1);
            }
            System.out.println(baos.toString());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 7.关闭Socket和相关的流
            try {
                baos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //服务端
    @Test
    public void server() {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        FileOutputStream fos = null;
        OutputStream os = null;
        try {
            // 1.创建ServerSocket
            int port = 9090;
            serverSocket = new ServerSocket(port);

            // 2.接收来自于客户端的socket:accept()
            socket = serverSocket.accept();

            // 3.通过Socket获取一个输入流
            is = socket.getInputStream();

            // 4.创建File类的实例、File0utputstream的实例
            File file = new File("huan_copy2.jpg");
            fos = new FileOutputStream(file);

            // 5.读写过程
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }

            // 6.服务端发送数据给客户端
            os = socket.getOutputStream();
            os.write("你的图片很漂亮,我接收到了".getBytes());

            System.out.println("数据接收完毕");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 7.关闭相关的Socket和流
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

【案例】聊天室

聊天室模型

在这里插入图片描述

服务器端

public class ChatSeverTest {
    //这个集合用来存储所有在线的客户端
    static ArrayList<Socket> online = new ArrayList<Socket>();

    public static void main(String[] args) throws IOException {
        //1、启动服务器,绑定端口号
        ServerSocket server = new ServerSocket(8989);

        //2、接收n多的客户端同时连接
        while (true) {
            Socket accept = server.accept();

            online.add(accept);//把新连接的客户端添加到online列表中

            MessageHandler mh = new MessageHandler(accept);
            mh.start();
        }
    }

    static class MessageHandler extends Thread {
        private Socket socket;
        private String ip;

        public MessageHandler(Socket socket) {
            super();
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                ip = socket.getInetAddress().getHostAddress();
                //插入:给其他客户端转发“我上线了”
                sendToOther(ip+"上线了");

                //(1)接收该客户端的发送的消息
                InputStream input = socket.getInputStream();
                InputStreamReader reader = new InputStreamReader(input);
                BufferedReader br = new BufferedReader(reader);

                String str;

                while ((str = br.readLine()) != null) {
                    //(2)给其他在线客户端转发
                    sendToOther(ip + ":" + str);
                }

                sendToOther(ip + "下线了");
            } catch (IOException e) {
                try {
                    sendToOther(ip + "掉线了");
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            } finally {
                //从在线人员中移除我
                online.remove(socket);
            }

        }

        //封装一个方法:给其他客户端转发xxx消息
        public void sendToOther(String message) throws IOException {
            //遍历所有的在线客户端,一一转发
            for (Socket on : online) {
                OutputStream every = on.getOutputStream();
                PrintStream ps = new PrintStream(every);

                ps.println(message);
            }
        }
    }
}

客户端

public class ChatClientTest {
    public static void main(String[] args) throws Exception {
        //1、连接服务器
        Socket socket = new Socket("127.0.0.1", 8989);

        //2、开启两个线程
        //(1)一个线程负责看别人聊,即接收服务器转发的消息
        Receive receive = new Receive(socket);
        receive.start();

        //(2)一个线程负责发送自己的话
        Send send = new Send(socket);
        send.start();

        send.join();//等我发送线程结束了,才结束整个程序

        socket.close();
    }
}

class Send extends Thread{
    private Socket socket;
    public Send(Socket socket) {
        super();
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            OutputStream outputStream = socket.getOutputStream();
            //按行打印
            PrintStream ps = new PrintStream(outputStream);
            Scanner input = new Scanner(System.in);

            //从键盘不断的输入自己的话,给服务器发送,由服务器给其他人转发
            while (true) {
                System.out.println("自己的话:");
                String str = input.nextLine();
                if ("bye".equals(str)) {
                    break;
                }
                ps.println(str);
            }

            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class Receive extends Thread{
    private Socket socket;
    public Receive(Socket socket) {
         super();
         this.socket = socket;
    }

    @Override
    public void run() {
        try {
            InputStream inputStream = socket.getInputStream();
            Scanner input = new Scanner(inputStream);

            while (input.hasNextLine()) {
                String line = input.nextLine();
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

UDP网络编程

通信模型

在这里插入图片描述

示例

public class UDPTest {
    
    //发送端
    @Test
    public void sender() throws Exception {
        //1.创建DatagramSocket的实例
        DatagramSocket ds = new DatagramSocket();

        //2、将数据、目的地的ip,目的地的端口号部封装在DatagramPacket数据报中
        InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
        int port = 9090;
        byte[] bytes = "我是发送端".getBytes("utf-8");
        DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, inetAddress, port);

        //发送数据
        ds.send(packet);
        ds.close();
    }

    //接收端
    @Test
    public void receiver() throws IOException {
        //1.创建DatagramSocket的实例
        int port = 9090;
        DatagramSocket ds = new DatagramSocket(port);

        //2. 创建数据报的对象,用于接收发送端发送过来的数据
        byte[] buffer = new byte[1024 * 64];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);

        //3.接收数据
        ds.receive(packet);

        //4.获取数据,并打印到控制台上
        String str = new String(packet.getData(), 0, packet.getLength());
        System.out.println(str);

        ds.close();
    }
}

URL编程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1932481.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(算法)区间调度问题

问题大致如下所述&#xff1a;有n项工作,每项工作分别在s时间开始,在t时间结束. 对于每项工作,你都可以选择参与与否,如果选择了参与,那么自始至终都必须全程参与. 此外,参与工作的时间段不能重复(即使是开始的瞬间和结束的瞬间的重叠也是不允许的). 你的目标是参…

数据结构历年考研真题对应知识点(哈夫曼树和哈夫曼编码)

目录 5.5.1哈夫曼树和哈夫曼编码 1.哈夫曼树的定义 2.哈夫曼树的构造 【分析哈夫曼树的路径上权值序列的合法性&#xff08;2010&#xff09;】 【哈夫曼树的性质&#xff08;2010、2019&#xff09;】 3.哈夫曼编码 【根据哈夫曼编码对编码序列进行译码&#xff08;201…

全文翻译 | OWASP《LLM安全与治理检查清单》

&#x1f4a1; 摘要&#xff1a; LLM AI Cybersecurity & Governace Checklist version 1.0 发布时间&#xff1a;2024年2月19日 本文是OWASP&#xff08;开放式网络应用安全项目&#xff09;发布的《LLM AI安全与治理清单》&#xff08;以下简称“清单”&#xff09;&…

使用Django框架实现音频上传功能

数据库设计&#xff08;models.py&#xff09; class Music(models.Model):""" 音乐 """name models.CharField(verbose_name"音乐名字", max_length32)singer models.CharField(verbose_name"歌手", max_length32)# 本质…

Java二十三种设计模式-工厂方法模式(2/23)

工厂方法模式&#xff1a;设计模式中的瑞士军刀 引言 在软件开发中&#xff0c;工厂方法模式是一种常用的创建型设计模式&#xff0c;它用于处理对象的创建&#xff0c;将对象的实例化推迟到子类中进行。这种模式不仅简化了对象的创建过程&#xff0c;还提高了代码的可维护性…

数据结构day2

一、思维导图 内存分配 二、课后习题 分文件编译 //sys.h #ifndef TEST_H #define TEST_H #define MAX_SIZE 100//定义学生类型 typedef struct Stu {char name[20]; //姓名int age; //年龄double score; //分数 }stu;//定义班级类型 typedef struct Class {struct …

4.作业--Jquery,JS

目录 作业题目&#xff1a;1.使用Jquery完成点击图片变换图片颜色 A图 B代码 HTML的部分 JQ的部分 作业题目&#xff1a;2.使用JS中的DOM操作完成背景颜色渐变方向变换。点击背景&#xff0c;渐变方向发生改变。 A图 B代码 学习产出&#xff1a; 作业题目&#xff1a;1…

2014-2024年腾势D9N7N8EVDMI维修手册和电路图资料线路图接线图

经过整理&#xff0c;2014-2024年腾势汽车全系列已经更新至汽修帮手资料库内&#xff0c;覆盖市面上99%车型&#xff0c;包括维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照表…

ORA-00756 ORA-10567故障处理---惜分飞

数据库异常断电之后&#xff0c;recover 报ORA-00756 ORA-10567等错 SQL> recover database; ORA-00756: 恢复操作检测到数据块写入丢失 ORA-10567: Redo is inconsistent with data block (file# 1,block# 113855,file offset is 932700160 bytes) ORA-10564: tablespace S…

【学术会议征稿】第四届人工智能、虚拟现实与可视化国际学术会议(AIVRV 2024)

第四届人工智能、虚拟现实与可视化国际学术会议&#xff08;AIVRV 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Virtual Reality and Visualization 第四届人工智能、虚拟现实与可视化国际学术会议&#xff08;AIVRV 2024&#xff09;将…

请你谈谈:spring bean的生命周期 - 阶段2:Bean实例化阶段

在Spring框架中&#xff0c;Bean的实例化是Bean生命周期中的一个重要阶段。这个过程包括两个关键的子阶段&#xff1a;Bean实例化前阶段和Bean实例化阶段本身。 BeanFactoryPostProcessor&#xff1a;BeanFactoryPostProcessor是容器启动阶段Spring提供的一个扩展点&#xff0…

科技出海|百分点科技智慧政务解决方案亮相非洲展会

近日&#xff0c;华为非洲全联接大会在南非约翰内斯堡举办&#xff0c;吸引政府官员行业专家、思想领袖、生态伙伴等2,000多人参会&#xff0c;百分点科技作为华为云生态合作伙伴&#xff0c;重点展示了智慧政务解决方案&#xff0c;发表《Enable a Smarter Government with Da…

Transformer系列专题(四)——Swintransformer

文章目录 九、SwinTransformer9.1 整体网络架构9.2 Transformer Blocks9.3 Patch Embedding&#xff08;将图像切割成小块&#xff08;Patch&#xff09;&#xff09;9.4 window_partition9.5 W-MSA&#xff08;Window Multi-head Self Attention&#xff09;9.6 window_revers…

LinuxShell编程2——shell搭建Discuzz论坛网站

目录 一、环境准备 ①准备一台虚拟机 ②初始化虚拟机 1、关闭防火墙 2、关闭selinux 3、配置yum源 4、修改主机名 二、搭建LAMP环境 ①安装httpd(阿帕奇apache&#xff09;服务器 查看是否安装过httpd 启动httpd 设置开机启动 查看状态 安装网络工具 测试 ②安装…

Android C++系列:Linux线程(三)线程属性

linux下线程的属性是可以根据实际项目需要,进行设置,之前我们讨论的线程都是采用线程的默认属性,默认属性已经可以解决绝大多数开发时遇到的问 题。如我们对程序的性能提出更高的要求那么需要设置线程属性,比如可以通过设置线程栈的大小来降低内存的使用,增加最大线程个数…

数据结构——栈和队列(C语言实现)

写在前面&#xff1a; 栈和队列是两种重要的线性结构。其也属于线性表&#xff0c;只是操作受限&#xff0c;本节主要讨论的是栈和队列的定义、表示方法以及C语言实现。 一、栈和队列的定义与特点 栈&#xff1a;是限定仅在表尾进行插入和删除的线性表。对栈来说&#xff0c;表…

【Elasticsearch7.11】reindex问题

参考博文链接 问题&#xff1a;reindex 时出现如下问题 原因&#xff1a;数据量大&#xff0c;kibana的问题 解决方法&#xff1a; 将DSL命令转化成CURL命令在服务上执行 CURL命令 自动转化 curl -XPOST "http://IP:PORT/_reindex" -H Content-Type: application…

防洪墙的安全内容检测+http请求头

1、华为的IAE引擎&#xff1a;内部工作过程 IAE引擎主要是针对2-7层进行一个数据内容的检测 --1、深度检测技术 (DPI和DPF是所有内容检测都必须要用到的技术) ---1、DPI--深度包检测&#xff0c;针对完整的数据包&#xff0c;进行内容的识别和检测 1、基于特征子的检…

Spark算子--take(访问量前十网站)

1.题目需求 利用数据集SogouQ2012.mini.tar.gz 将数据按照访问次数进行排序&#xff0c;求访问量前10的网址&#xff0c;每一行数据代表一个url被访问1次 2.代码 from pyspark import SparkContext, SparkConfdef main():conf SparkConf().setMaster("local[*]").s…

【操作系统】文件管理——文件存储空间管理(个人笔记)

学习日期&#xff1a;2024.7.17 内容摘要&#xff1a;文件存储空间管理、文件的基本操作 在上一章中&#xff0c;我们学习了文件物理结构的管理&#xff0c;重点学习了操作系统是如何实现逻辑结构到物理结构的映射&#xff0c;这显然是针对已经存储了文件的磁盘块的&#xff0…