Java多线程编程实现socket通信示例代码

Java多线程编程实现socket通信是一种常见的方式,通常用于编写网络服务器程序。本文将提供一个完整的攻略,首先介绍Java多线程编程的概述,然后描述如何使用Java多线程编程实现socket通信,最后给出两个示例代码。

概述

多线程编程是一种同时执行多个任务的编程技术。Java是一种多线程支持的编程语言,具有良好的多线程支持。Java多线程编程允许程序同时执行多个任务,提高程序的性能。

Socket通信是一种面向网络通信的技术,用于在网络上传输数据。Java提供了Socket类和ServerSocket类来实现Socket通信。

Java多线程编程实现Socket通信

Java多线程编程可以很好地支持Socket通信。使用多线程编程可以实现同时处理多个客户端的请求。基本的步骤如下:

  1. 创建ServerSocket并绑定端口。

  2. 循环调用accept()方法来监听客户端的连接请求。

  3. 对于每个连接请求,创建一个新的线程来处理。

  4. 在每个线程中,调用Socket.getInputStream()方法来获取客户端发送的数据,并将结果发送回客户端。

下面给出两个示例代码,第一个示例实现了一个简单的计算器服务,客户端可以通过Socket向服务端发送计算表达式并获取计算结果。第二个示例实现一个简单的聊天室,客户端可以在聊天室中发送消息和接收其他客户端的消息。

示例1:计算器服务

  1. 服务端代码:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class CalculatorServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(1234);
        System.out.println("Calculator server started...");

        // 循环监听客户端连接请求
        while (true) {
            Socket socket = serverSocket.accept();
            System.out.println("Client connected from " + socket.getInetAddress());

            // 创建一个新线程来处理客户端请求
            Thread thread = new CalculatorThread(socket);
            thread.start();
        }
    }
}

class CalculatorThread extends Thread {
    private Socket socket;

    public CalculatorThread(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            // 读取客户端发送的计算表达式
            String expr = SocketUtil.readLine(socket.getInputStream());
            System.out.println("Received expression: " + expr);

            // 计算表达式并返回结果
            int result = Calculator.calculate(expr);
            SocketUtil.writeLine(socket.getOutputStream(), Integer.toString(result));
            System.out.println("Sent result: " + result);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class Calculator {
    public static int calculate(String expr) {
        // 解析表达式并计算结果
        return eval(expr);
    }

    private static int eval(String expr) {
        // 实现表达式的解析和计算
        return 0;
    }
}

class SocketUtil {
    public static void writeLine(OutputStream out, String line) throws IOException {
        out.write((line + "\n").getBytes());
    }

    public static String readLine(InputStream in) throws IOException {
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        while (true) {
            int b = in.read();
            if (b == -1) {
                throw new EOFException("End of input");
            }
            if (b == '\n') {
                break;
            }
            buf.write(b);
        }
        return buf.toString();
    }
}

该示例中使用ServerSocket来监听客户端连接请求,并为每个客户端连接创建一个新的线程。每个线程用于处理客户端发送的计算表达式,计算结果并将结果返回给客户端。

2.客户端代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class CalculatorClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 1234);
        System.out.println("Connected to calculator server");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        // 循环读取用户输入的计算表达式
        while (true) {
            System.out.print("Enter an expression (or \"quit\" to exit): ");
            String expr = reader.readLine();
            if ("quit".equals(expr)) {
                break;
            }

            // 向服务器发送计算表达式并读取结果
            SocketUtil.writeLine(socket.getOutputStream(), expr);
            String result = SocketUtil.readLine(socket.getInputStream());
            System.out.println("Result: " + result);
        }

        socket.close();
        System.out.println("Disconnected from calculator server");
    }
}

该示例中客户端通过Socket向服务端发送计算表达式并获取计算结果,运行示例前需要先启动服务端。

示例2:聊天室

  1. 服务端代码:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class ChatServer {
    private static List<ChatThread> threads = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(1234);
        System.out.println("Chat server started...");

        // 循环监听客户端连接请求
        while (true) {
            Socket socket = serverSocket.accept();
            System.out.println("Client connected from " + socket.getInetAddress());

            // 创建一个新线程来处理客户端请求
            ChatThread thread = new ChatThread(socket);
            threads.add(thread);
            thread.start();
        }
    }

    public static void broadcast(String message) {
        // 广播消息给所有客户端
        for (ChatThread thread : threads) {
            thread.sendMessage(message);
        }
    }

    public static void removeThread(ChatThread thread) {
        // 从列表中移除线程
        threads.remove(thread);
    }
}

class ChatThread extends Thread {
    private Socket socket;
    private String username;

    public ChatThread(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            // 读取客户端发送的用户名
            username = SocketUtil.readLine(socket.getInputStream());
            System.out.println("User " + username + " logged in");

            // 广播欢迎消息
            ChatServer.broadcast(username + " joined the chat");

            // 循环读取客户端发送的消息并广播给其他客户端
            while (true) {
                String message = SocketUtil.readLine(socket.getInputStream());
                ChatServer.broadcast(username + ": " + message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            ChatServer.removeThread(this);
            ChatServer.broadcast(username + " left the chat");
        }
    }

    public void sendMessage(String message) {
        // 发送消息给该客户端
        try {
            SocketUtil.writeLine(socket.getOutputStream(), message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

该示例中使用ServerSocket来监听客户端连接请求,并为每个客户端连接创建一个新的线程。每个线程用于循环读取客户端发送的消息并广播给其他客户端。

  1. 客户端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class ChatClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 1234);
        System.out.println("Connected to chat server");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        // 读取用户输入的用户名
        System.out.print("Enter your username: ");
        String username = reader.readLine();

        // 发送用户名给服务器并启动一个新线程来循环读取消息
        SocketUtil.writeLine(socket.getOutputStream(), username);
        Thread thread = new Thread(new ChatReader(socket));
        thread.start();

        // 循环读取用户输入的消息并发送给服务器
        while (true) {
            String message = reader.readLine();
            SocketUtil.writeLine(socket.getOutputStream(), message);
        }
    }
}

class ChatReader implements Runnable {
    private Socket socket;

    public ChatReader(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            // 循环读取来自服务器的消息并输出到控制台
            while (true) {
                String message = SocketUtil.readLine(socket.getInputStream());
                System.out.println(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

该示例中客户端可以在聊天室中发送消息和接收其他客户端的消息,运行示例前需要先启动服务端。

以上就是Java多线程编程实现socket通信的完整攻略介绍,希望对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程编程实现socket通信示例代码 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • java 字符串相减(很简单的一个方法)

    Java中的字符串是不可修改的,也就是说,字符串变量一旦被创建,它的值就不能改变。因此,不能像数字那样直接相减。但是,可以使用一种简单的方法来实现字符串相减的效果。 具体来说,可以将一个字符串中的另一个字符串删除,实现字符串相减的效果。下面给出两个示例说明: 示例一: String str1 = "hello world"; String…

    Java 2023年5月26日
    00
  • Java swing实现支持录音等功能的钢琴程序

    如何实现Java Swing支持录音等功能的钢琴程序? 导入所需库文件 实现这个功能的Java库有很多,我们可以使用Java Sound API、Java Media Framework、JLGui和JLayer。为了方便起见,我们在这里使用Java Sound API来实现这个功能。我们需要导入下面的库文件: <dependency> <…

    Java 2023年5月23日
    00
  • 详解Spring Boot 集成Shiro和CAS

    详解Spring Boot 集成Shiro和CAS Shiro是一个非常流行的Java安全框架,它提供了一种方便的方式来处理身份验证、授权和加密等安全问题。CAS(Central Authentication Service)是一个单点登录协议,它允许用户在多个应用程序中使用同一组凭据进行身份验证。本文将详细介绍如何在Spring Boot中集成Shiro和…

    Java 2023年5月17日
    00
  • 详解非spring框架下使用querydsl的方法

    下面为您详细讲解“详解非Spring框架下使用Querydsl的方法”的完整攻略。 什么是Querydsl? Querydsl是一个用于构建类型安全查询的框架,它支持多种关系型数据库和NoSQL数据存储的查询,可以通过Java8 Lambda表达式实现清晰、易读的DSL查询语法。 在非Spring框架下使用Querydsl的方法 1. 引入相关依赖 在Mav…

    Java 2023年5月20日
    00
  • Java API方式调用Kafka各种协议的方法

    Java API方式调用Kafka的方法主要是通过Kafka提供的各种API来实现。其中,Kafka提供了多种协议,包括生产、消费、管理、复制等,下面我们逐一介绍如何使用Java API来调用它们。 一、生产消息 生产消息是Kafka最基础的功能之一,以下是使用Java API来生产消息的步骤: 1.导入相关依赖 <dependency> &lt…

    Java 2023年5月20日
    00
  • 如何编写Java单元测试?

    当我们编写Java代码时,单元测试是非常重要的一部分。它可以帮助我们在开发过程中就确定代码是否正确,而不必等到部署到实际环境中才发现问题。本篇文章将会给出针对Java代码的单元测试的完整攻略。 步骤一:选择合适的单元测试框架 在Java中,有很多单元测试框架可供选择,包括JUnit、TestNG、Spock等。其中,JUnit是最常用的框架之一。本文将以JU…

    Java 2023年5月11日
    00
  • Java 字节数组类型(byte[])与int类型互转方法

    Java 字节数组类型(byte[])与int类型互转方法可以使用Java内置的ByteArrayInputStream和DataInputStream类,以及ByteArrayOutputStream和DataOutputStream类实现。下面将详细讲解这两种方法的具体实现和使用。 方法一:使用byte数组和流进行互转 byte[]类型转int类型示例 …

    Java 2023年5月26日
    00
  • SpringBoot整合FastDFS方法过程详解

    下面详细讲解SpringBoot整合FastDFS的方法。 简介 FastDFS是一个开源的轻量级分布式文件系统,它主要解决了海量图片、音视频等文件存储和访问的问题。Spring Boot是一种基于Spring框架的快速开发个性化应用的框架。本文将详细介绍Spring Boot如何整合FastDFS实现文件上传和下载功能。 步骤 1. 添加FastDFS依赖…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部