java—网络编程TCP和UDP

1. Java 网络编程概述

Java 网络编程是通过 java.net 包实现的,Socket 类是用来进行客户端与服务器通信的主要类。服务器端通过 ServerSocket 类来监听客户端的请求,客户端则通过 Socket 类来连接服务器。

2. TCP 网络编程示例

TCP 通信中,数据传输是可靠的,确保了数据的顺序和完整性。以下是一个简单的客户端和服务器应用,其中服务器端监听指定端口,客户端向服务器发送消息并接收响应。

2.1 TCP 服务器端
import java.io.*;
import java.net.*;

public class TCPServer {
    public static void main(String[] args) {
        try {
            // 创建ServerSocket对象,监听端口12345
            ServerSocket serverSocket = new ServerSocket(12345);
            System.out.println("Server is listening on port 12345...");

            while (true) {
                // 等待客户端连接
                Socket clientSocket = serverSocket.accept();
                System.out.println("New client connected: " + clientSocket.getInetAddress());

                // 创建线程来处理客户端请求
                Thread clientThread = new Thread(new ClientHandler(clientSocket));
                clientThread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class ClientHandler implements Runnable {
    private Socket clientSocket;

    public ClientHandler(Socket socket) {
        this.clientSocket = socket;
    }

    @Override
    public void run() {
        try {
            // 获取客户端输入和输出流
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

            // 读取客户端发送的消息
            String message = in.readLine();
            System.out.println("Received from client: " + message);

            // 发送响应给客户端
            out.println("Hello from server!");

            // 关闭连接
            clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2 TCP 客户端
import java.io.*;
import java.net.*;

public class TCPClient {
    public static void main(String[] args) {
        try {
            // 创建Socket对象连接到服务器
            Socket socket = new Socket("localhost", 12345);
            System.out.println("Connected to the server");

            // 获取输入输出流
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            // 向服务器发送消息
            out.println("Hello from client!");

            // 接收服务器响应
            String response = in.readLine();
            System.out.println("Received from server: " + response);

            // 关闭连接
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行步骤

  1. 先启动 TCPServer,它将监听端口 12345。
  2. 然后启动 TCPClient,它将连接到服务器并发送消息。

输出示例

  • 服务器端

    Server is listening on port 12345...
    New client connected: /127.0.0.1
    Received from client: Hello from client!
    
    
  • 客户端

    Connected to the server
    Received from server: Hello from server!
    
    

3. UDP 网络编程示例

UDP 是一种无连接、不保证可靠性的协议,适用于实时性要求高,但对数据丢失不敏感的场景(如视频流、在线游戏等)。

3.1 UDP 服务器端
import java.net.*;

public class UDPServer {
    public static void main(String[] args) {
        try {
            // 创建UDP服务器端套接字
            DatagramSocket serverSocket = new DatagramSocket(12345);
            System.out.println("UDP Server is listening on port 12345...");

            byte[] receiveData = new byte[1024];

            while (true) {
                // 创建数据报包来接收客户端消息
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivePacket);

                // 获取客户端地址和数据
                String clientMessage = new String(receivePacket.getData(), 0, receivePacket.getLength());
                System.out.println("Received from client: " + clientMessage);

                // 发送响应给客户端
                InetAddress clientAddress = receivePacket.getAddress();
                int clientPort = receivePacket.getPort();
                String responseMessage = "Hello from UDP server!";
                DatagramPacket sendPacket = new DatagramPacket(responseMessage.getBytes(), responseMessage.length(), clientAddress, clientPort);
                serverSocket.send(sendPacket);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.2 UDP 客户端

import java.net.*;

public class UDPClient {
    public static void main(String[] args) {
        try {
            // 创建UDP客户端套接字
            DatagramSocket clientSocket = new DatagramSocket();
            InetAddress serverAddress = InetAddress.getByName("localhost");

            // 发送消息给服务器
            String message = "Hello from UDP client!";
            DatagramPacket sendPacket = new DatagramPacket(message.getBytes(), message.length(), serverAddress, 12345);
            clientSocket.send(sendPacket);

            // 接收服务器的响应
            byte[] receiveData = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            clientSocket.receive(receivePacket);

            // 显示服务器响应
            String response = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("Received from server: " + response);

            // 关闭客户端套接字
            clientSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 

运行步骤

  1. 先启动 UDPServer,它将监听端口 12345。
  2. 然后启动 UDPClient,它将向服务器发送消息并接收响应。

输出示例

  • 服务器端

    UDP Server is listening on port 12345...
    Received from client: Hello from UDP client!
    
    
  • 客户端

    Received from server: Hello from UDP server!
    

4. 多线程和线程池示例

为了处理多个客户端的连接,可以使用 多线程 来为每个客户端创建独立的处理线程。此外,使用 线程池 可以有效地管理线程,提高服务器的性能。

4.1 使用线程池管理客户端请求

(1)线程池版的 TCP 服务器

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class ThreadPoolTCPServer {
    private static final int PORT = 12345;

    public static void main(String[] args) {
        try {
            // 创建线程池
            ExecutorService threadPool = Executors.newFixedThreadPool(10);

            // 创建ServerSocket并监听端口
            ServerSocket serverSocket = new ServerSocket(PORT);
            System.out.println("Server is listening on port " + PORT);

            while (true) {
                // 接受客户端连接
                Socket clientSocket = serverSocket.accept();
                System.out.println("New client connected: " + clientSocket.getInetAddress());

                // 将客户端连接交给线程池处理
                threadPool.submit(new ClientHandler(clientSocket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static class ClientHandler implements Runnable {
        private Socket clientSocket;

        public ClientHandler(Socket socket) {
            this.clientSocket = socket;
        }

        @Override
        public void run() {
            try {
                // 获取输入输出流
                BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

                // 处理客户端请求
                String message = in.readLine();
                System.out.println("Received from client: " + message);
                out.println("Hello from server!");

                // 关闭连接
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

多线程和线程池的优势

  • 使用 线程池 可以避免频繁创建和销毁线程,从而提升性能。
  • 每个客户端连接都会分配一个线程,线程池确保了线程的复用。

喜欢这期内容的话,别忘了点个赞,关注博主,这样就不会错过任何更新啦!还有,收藏一下,方便以后回顾哦!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Design Compiler:两种工作模式(线负载模式和拓扑模式)

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 Design Compiler可以以线负载模式或拓扑模式启动,必须选择其中一个模式。在拓扑模式下还可使用多模式和UPF模式:多模式允许在多种工作…

应急响应练习

文章目录 web1web2 web1 题目要求: 前景需要: 小李在值守的过程中,发现有CPU占用飙升,出于胆子小,就立刻将服务器关机,这是他的服务器系统,请你找出以下内容,并作为通关条件&#…

从零开始构建直播APP美颜功能:直播美颜SDK的开发实践指南

本文将从零开始,详细探讨如何开发一款功能完善的直播美颜SDK,帮助开发者快速集成美颜功能。 一、明确需求与功能设计 开发美颜功能的第一步是明确需求。直播场景中的美颜需求通常包括以下几点: 实时滤镜:提供多种风格的滤镜&am…

.NET周刊【12月第4期 2024-12-22】

国内文章 dotnet 简单使用 ICU 库进行分词和分行 https://www.cnblogs.com/lindexi/p/18622917 本文将和大家介绍如何使用 ICU 库进行文本的分词和分行。 dotnet 简单聊聊 Skia 里的 SKFontMetrics 的各项属性作用 https://www.cnblogs.com/lindexi/p/18621674 本文将和大…

vue3大屏实现;使用使用CSS Grid实现大屏

文章目录 一、效果1.效果2.使用CSS Grid3.插件4.html代码5.index.scss代码 一、效果 1.效果 方案:采用CSS的Grid布局,实现首页大屏模块划分和自适应功能; 布局: 大屏主要内容,高宽比是1920*1080;即16:9的…

基于FISCO BCOS的电子签署系统

概述 本项目致力于构建一个安全、高效且功能完备的电子签署系统,通过整合区块链技术与传统数据库管理,为用户提供了可靠的电子签署解决方案,有效应对传统电子签署系统的数据安全隐患,满足企业和个人在数字化办公环境下对电子文档…

【PCIe 总线及设备入门学习专栏 5 -- PCIE接头引脚定义】

文章目录 PCIe 硬件接口 pin 本文转自:小K 硬件会 2024年09月03日 19:35 北京 PCIe 硬件接口 pin 在使用 PCIe 接口时,可以将 PCIe 金手指插入任何不短于金手指长度的 PCIe 插槽中。比如: x1 的 PCIe 金手指可以插入 x1、x4、x8 和 x16 的…

【开源免费】基于SpringBoot+Vue.JS大型商场应急预案管理系统(JAVA毕业设计)

本文项目编号 T 105 ,文末自助获取源码 \color{red}{T105,文末自助获取源码} T105,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

【鸿蒙NEXT】鸿蒙里面类似iOS的Keychain——关键资产(@ohos.security.asset)实现设备唯一标识

前言 在iOS开发中Keychain 是一个非常安全的存储系统,用于保存敏感信息,如密码、证书、密钥等。与 NSUserDefaults 或文件系统不同,Keychain 提供了更高的安全性,因为它对数据进行了加密,并且只有经过授权的应用程序才…

VBA批量插入图片到PPT,一页一图

Sub InsertPicturesIntoSlides()Dim pptApp As ObjectDim pptPres As ObjectDim pptSlide As ObjectDim strFolderPath As StringDim strFileName As StringDim i As Integer 设置图片文件夹路径strFolderPath "C:\您的图片文件夹路径\" 请替换为您的图片文件夹路径…

【Gitlab】详细介绍与安装配置指南

🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、什么是Gitlab 2、Gitlab起源 二、GitLab的核心功能 …

Mcnemar‘s exact test

与卡方检验的区别 与fisher exact test区别

从手术到诊断:Tekceleo超声波压电电机的全面医疗应用

在当今医疗领域,技术的不断创新正在推动传统医疗模式向更精准、更高效的方向转变。Tekceleo公司凭借其超声波压电电机技术,在医疗行业中逐步占据重要地位,为医疗操作的精准化与高效化做出了显著贡献。 Tekceleo超声波压电电机的技术特点 Tek…

Postman[3] 创建Get和Post请求

1.创建Get请求 以打开百度页面为例 链接:https://www.baidu.com/ 步骤: 1.1新建一个Collection 1.2Add Request 1.3填充请求的url 1.4 Send 1.5检查返回结果 注意:这里和我们打开网页看到的页面不一样,是因为缺少请求头&…

C# OpenCV机器视觉:姿态估计

在一个阴沉沉的下午,天空仿佛被一块巨大的灰色抹布盖住,细雨淅淅沥沥地洒着,阿强正在实验室里捣鼓他那些宝贝仪器,活像一个正在摆弄玩具的大孩子。突然,同事小杨像只没头的苍蝇一样冲了进来,脸上写满了困惑…

自动化测试模型(一)

8.8.1 自动化测试模型概述 在自动化测试运用于测试工作的过程中,测试人员根据不同自动化测试工具、测试框架等所进行的测试活动进行了抽象,总结出线性测试、模块化驱动测试、数据驱动测试和关键字驱动测试这4种自动化测试模型。 线性测试 首先&#…

语音识别基础算法——动态时间规整算法

前言 动态时间规整算法,Dynamic Time Wraping,缩写为DTW,是语音识别领域的一个基础算法。 算法的提出 DTW 的提出是为了解决或尽量解决在语音识别当中的孤立词识别不正确的问题。该问题简单描述为:在识别阶段,将输入…

Word论文交叉引用一键上标

Word论文交叉引用一键上标 1.进入Microsoft word使用CtrlH快捷键或单击替换按钮 2.在查找内容中输入[^#] 3.鼠标点击,标签为“替换为:”的文本框,注意光标一定要打在图红色方框圈中的文本框中! 4.点击格式选择字体 5.勾选上标…

BLIP论文笔记

论文地址 BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation 论文思想 其实Clip就相当于只用了ITC

适用于项目经理的跨团队协作实践:Atlassian Jira与Confluence集成

适用于项目经理的跨团队协作实践:Atlassian Jira与Confluence集成 现代项目经理的核心职责是提供可视性、保持团队一致,并确保团队拥有交付出色工作所需的资源。在过去几年中,由于分布式团队的需求不断增加,项目经理这一角色已迅速…