Java编程实现多线程TCP服务器完整实例

Java编程实现多线程TCP服务器完整实例

简介

本文将通过Java代码实现一个多线程的TCP服务器,包含完整的代码以供参考。该服务器能够同时服务多个客户端,每个客户端都在独立的线程中运行。本文将介绍如何实现TCP Socket编程,以及如何使用Java多线程进行并发编程。

实现目标

  1. 实现一个多线程TCP服务器,支持多客户端同时连接。
  2. 服务器能够接受客户端连接,并读取并输出客户端发送的消息。
  3. 服务器能够向客户端发送消息,并关闭连接。

代码实现

以下是实现该目标的Java代码,我们对其进行分析:

import java.io.*;
import java.net.*;

public class MultithreadedTCPServer {
    public static void main(String[] args) throws IOException {
        //创建一个ServerSocket监听端口
        int portNumber = 5000;
        try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
            System.out.println("服务器启动,监听端口号: " + portNumber);
            //循环等待客户端连接
            while (true) {
                //客户端连接成功,创建新的Socket来处理客户端请求
                new ClientThread(serverSocket.accept()).start();
            }
        } catch (IOException e) {
            System.err.println("无法监听端口 " + portNumber);
            System.exit(-1);
        }
    }
}

//处理客户端请求的线程类
class ClientThread extends Thread {
    private Socket socket;
    private PrintWriter out;
    private BufferedReader in;

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

    public void run() {
        try {
            System.out.println("客户端连接成功。地址:" + socket.getRemoteSocketAddress());

            //获取Socket的输入输出流,用于向客户端发送和接收消息
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                //客户端发送了"Bye"时,关闭连接
                if (inputLine.equals("Bye")) {
                    break;
                }
                //向客户端发送消息
                out.println("服务器响应:" + inputLine);
            }

            //关闭连接
            out.close();
            in.close();
            socket.close();
            System.out.println("客户端断开连接。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码实现分析

程序入口

程序入口使用了Java的main方法,其创建了一个ServerSocket并循环等待客户端的连接。

int portNumber = 5000;
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
    System.out.println("服务器启动,监听端口号: " + portNumber);
    //循环等待客户端连接
    while (true) {
        //客户端连接成功,创建新的Socket来处理客户端请求
        new ClientThread(serverSocket.accept()).start();
    }
} catch (IOException e) {
    System.err.println("无法监听端口 " + portNumber);
    System.exit(-1);
}

其创建一个ServerSocket并绑定在5000端口,表示该服务器将会监听5000端口连接请求。当客户端连接时,主线程将创建一个新的ClientThread线程,并传入连接的Socket作为参数,然后启动该线程。

客户端线程

当客户端连接时,程序将通过一个ClientThread对象来处理客户端请求。该线程需要完成以下任务:

  1. 获取Socket的输入输出流,用于向客户端发送和接收消息。
  2. 读取客户端发送的消息,并向客户端发送响应消息。
  3. 关闭连接。
class ClientThread extends Thread {
    private Socket socket;
    private PrintWriter out;
    private BufferedReader in;

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

    public void run() {
        try {
            System.out.println("客户端连接成功。地址:" + socket.getRemoteSocketAddress());

            //获取Socket的输入输出流,用于向客户端发送和接收消息
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                //客户端发送了"Bye"时,关闭连接
                if (inputLine.equals("Bye")) {
                    break;
                }
                //向客户端发送消息
                out.println("服务器响应:" + inputLine);
            }

            //关闭连接
            out.close();
            in.close();
            socket.close();
            System.out.println("客户端断开连接。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

该线程包含了一个私有成员变量Socket,一个PrintWriter对象用于向客户端发送消息,一个BufferedReader对象用于接收客户端的消息。

当客户端连接服务器时,线程的run方法会被执行。在该方法中,首先获取了Socket的输入输出流,用于向客户端发送和接收消息。接着,它会读取客户端发送的消息,并向客户端发送响应消息。当客户端发送了"Bye"时,该线程将关闭连接。

示例

示例1

现在我们可以启动服务器,这可以通过执行MultithreadedTCPServer类的main方法来实现。当服务器开始监听端口时,我们可以启动多个客户端,这通过执行以下客户端代码和使用telnet命令行工具来实现:

import java.io.*;
import java.net.*;

public class TCPClient {
    public static void main(String[] args) throws IOException {
        String hostName = args[0];
        int portNumber = Integer.parseInt(args[1]);

        try (
            Socket socket = new Socket(hostName, portNumber);
            PrintWriter out =
                new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in =
                new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
            BufferedReader stdIn =
                new BufferedReader(
                    new InputStreamReader(System.in))
        ) {
            String userInput;
            while ((userInput = stdIn.readLine()) != null) {
                out.println(userInput);
                System.out.println("服务器响应: " + in.readLine());
                if (userInput.equals("Bye"))
                    break;
            }
        } catch (UnknownHostException e) {
            System.err.println("无法确定主机: " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("无法连接到主机: " + hostName);
            System.exit(1);
        }
    }
}

执行代码java TCPClient localhost 5000可以启动一个客户端并连接到之前启动的服务器。这将打开一个输入流,可以在其中输入消息并将其发送到服务器。服务器会处理这些请求,然后返回响应消息。

示例2

我们可以使用telnet命令来手动连接到之前启动的服务器。在终端输入命令telnet localhost 5000 就能连接到服务器。输入消息并按Enter键发送,服务器将会打印出消息并返回响应消息。当要断开连接时,输入"Bye"即可关闭TCP连接。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java编程实现多线程TCP服务器完整实例 - Python技术站

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

相关文章

  • Java如何实现登录token令牌

    Java实现登录token令牌的方法有多种,一种较为常见的方式是利用JSON Web Token(JWT)。 什么是JWT? JWT是一种开放标准(RFC 7519),可以在不同应用程序之间安全地传递信息,该信息可以进行身份验证和授权。JWT包含三部分:头部,载荷(也称为声明)和签名。头部通常包含使用的签名算法,载荷包含请求的用户数据和其他元数据,签名用于验…

    Java 2023年5月26日
    00
  • Servlet服务端实现原理详解

    一、Servlet服务端实现原理 在Web应用中,服务端可以通过Java的Servlet技术实现对客户端(浏览器)的响应。Servlet是运行在服务端的Java程序,实现了应用服务器与客户端(浏览器)之间的通讯和数据交换。Servlet是一种通用的、基于Java的服务器端组件技术,它是在服务器端动态生成Web页面或进行数据处理的主要手段之一。 Servlet…

    Java 2023年6月15日
    00
  • SpringBoot如何实现starter原理详解

    下面是对“SpringBoot如何实现starter原理详解”的详细讲解: 什么是starter 在Spring Boot中,starter是一种基于依赖项的,提供了与特定目标功能相关的,预配置的Spring配置的实现方式。它为应用程序的开发者提供了一种快速启动他们的应用程序所需的依赖项和配置的方法。 在常见的web应用程序中,启动应用程序需要一定程度的常规…

    Java 2023年5月15日
    00
  • 深入浅出Java中重试机制的多种方式

    深入浅出Java中重试机制的多种方式 在开发中,有时会需要对某些操作进行多次尝试,以增加操作的稳定性和可靠性。这时,使用重试机制可以很好地解决这一问题。本文将详细介绍Java中重试机制的多种实现方式。 1. 基于while循环的重试机制 最简单的重试机制就是在while循环中执行某个操作,并在某些限定条件下进行多次尝试。例如以下示例代码: int count…

    Java 2023年5月27日
    00
  • java 将jsonarray 转化为对应键值的jsonobject方法

    将JSON数组转换为对应键值的JSON对象的过程可以通过Java编程实现。要使用Java转换JSON,我们可以使用Java中的org.json库。该库为JSON提供了一组内置API,可用于在Java应用程序中构建、解析和修改JSON内容。 下面是将JSONArray转换成具有对应键值的JSONObject的步骤: 1.从JSONArray中获取JSON对象的…

    Java 2023年5月26日
    00
  • java socket实现聊天室 java实现多人聊天功能

    下面为您详细讲解 Java Socket 实现聊天室的完整攻略。 一、概述 Java Socket 是 Java 语言提供的一种基于网络通信的 API,它可以实现两台或多台计算机之间的数据交换。聊天室是一种基于网络通信的应用程序,Java Socket 可以通过编写网络通信代码来实现聊天室功能。 二、实现步骤 1. 创建 Socket 服务器 首先需要创建一…

    Java 2023年5月24日
    00
  • 浅谈java 字符串,字符数组,list间的转化

    标题:浅谈Java字符串、字符数组、List间的转换 一、Java字符串、字符数组的转换 1.1 字符串转换为字符数组 可以使用 toCharArray() 方法将字符串转换为字符数组: String str = "hello"; char[] charArray = str.toCharArray(); // charArray = {…

    Java 2023年5月26日
    00
  • 使用spring的restTemplate注意点

    使用Spring的RestTemplate是在Java中向REST API发送HTTP请求的一种常见方法。它提供了许多方便的方法来处理HTTP请求和响应。使用RestTemplate时需要注意以下几点。 注意点一:配置RestTemplate的HttpClient RestTemplate的默认实现使用HttpURLConnection作为底层客户端,然而在…

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