当前位置: 首页 > article >正文

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();
            }
        }
    }
}

多线程和线程池的优势

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

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


http://www.kler.cn/a/459614.html

相关文章:

  • idea 的 springboot项目spring-boot-devtools 自动编译 配置热部署
  • 大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!
  • Unity 对Sprite或者UI使用模板测试扣洞
  • Nacos服务注册和发现
  • 面试经典问题 —— 链表之返回倒数第k个节点(经典的双指针问题)
  • 【人工智能机器学习基础篇】——深入详解强化学习之常用算法Q-Learning与策略梯度,掌握智能体与环境的交互机制
  • 探索RAG(检索增强生成):三大RAG技术的特点与应用场景
  • 分子动力学中优化算法和积分算法
  • CountDownLatch 和 CyclicBarrier
  • 【最新】西陆房产系统源码+uniapp全开源+环境教程
  • 【Logback详解】
  • 《代码随想录》Day17打卡
  • JVM 性能监控工具之命令行篇
  • 小程序配置文件 —— 13 全局配置 - window配置
  • 0041__OpenGL ES: (2) OpenGL ES 与 EGL、GLSL的关系
  • 基于特征工程(pca分析)、小波去噪以及数据增强,同时采用基于注意力机制的BiLSTM、随机森林、ARIMA模型进行序列数据预测
  • 使用Python实现量子算法优化:探索量子计算的无限可能
  • Spark Runtime Filter
  • 人才公寓系统|Java|SSM|JSP|
  • Python爬虫 - 豆瓣电影排行榜数据爬取、处理与存储
  • 基于西湖大学强化学习课程的笔记
  • C语言 练习
  • THM:Mouse Trap[WriteUP]
  • sentinel集成nacos启动报[check-update] get changed dataId error, code: 403错误排查及解决
  • 路由器OSPF动态路由配置
  • 解锁动态规划的奥秘:从零到精通的创新思维解析(3)