news 2026/4/18 10:31:29

[服务器应用开发教程]第二节-使用java让服务器忙起来

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[服务器应用开发教程]第二节-使用java让服务器忙起来

第一部分:为什么是java?如何在liunx上安装java?

最核心的一点:java“一次编写,到处运行” 的理念给予了它极为优异的跨平台性能。Java 支持 Linux、Windows、ARM/x86 等环境,并与 Kubernetes、Docker 无缝集成。

只要你的电脑上安装了java jdk环境,无论是Windows还是liunx都可以运行java应用,所以我们的第一步,就是为服务器配置java环境:

方法一:使用宝塔面板安装java jdk:

在软件商店中搜索“java环境管理器”,然后下载安装,完成后打开它:

再选择相应版本安装即可。

方法二:在终端进行操作:

这里以Ubuntu系统安装java17为例:

sudo apt update sudo apt install openjdk-17-jdk -y

无论哪种方法,在安装完成后都可以查询java版本验证:

java -version

如果安装成功,终端会输出如下信息:

第二部分:基于WebSocket的服务器通信原理及简单的信息处理尝试

我们现在知道服务器的ip了,那我们该如何让我们的本地计算机链接到它呢?

答案是使用WebSocket。WebSocket是一种重要的网络通信协议,属于传输层之上的应用层协议,提供全双工通信通道,允许客户端与服务器双向传输数据,提供了一套api接口来使计算机之间能够建立链接。几乎所有的编程语言都支持WebSocket。我们熟知的spring框架中的spring WebSocket就是对前者的封装。

在实际应用中,我们需要根据实际情况来选择使用WebSocket还是spring WebSocket:

WebSocket虽然在编程调用上比较麻烦,但功能可扩展性高。原生 WebSocket 支持通过 RFC 6455 定义的扩展机制(如permessage-deflate压缩、心跳检测)动态增强协议功能,适用于需要深度定制的场景(如高吞吐量二进制数据传输)。

Spring WebSocket在编程使用的简便性上更优,相应的它的扩展灵活性相对弱于前者。Spring WebSocket 通过@MessageMapping@SubscribeMapping等注解,将消息路由和处理逻辑封装为类似 Spring MVC 的声明式编程模型,开发者无需手动处理连接生命周期(如onopenonmessage事件)或底层帧解析。

具体到通信协议中的TCP协议、UDP协议等等我们后面再详细去讲,简单来说,这些协议规定了客户端与服务器之间谁怎样发送数据,谁又如何接收数据等等。

接下来我们讲解基于WebSocket的服务器通信实现功能的关键字段(为方便读代码,这些代码简化去除了异常处理类),假定我们要实现的功能是客户端发送两个数字A和B,服务器返回C=A+B,代码分为服务器端(cloud)与客户端(local)(完整代码在放在最后):

第一步,在本地构造一个包含了服务器ip与端口的local:

//local.java public local(String serverIp, int serverPort) { this.serverIp = serverIp; //服务器ip this.serverPort = serverPort; //服务器端口 }

第二步,创建socket在客户端的服务进程:

//local.java public int sendAndProcessData(int a, int b) throws IOException { Socket socket = new Socket(serverIp, serverPort); // 创建(实例化)客户端套接字,连接到指定IP地址和端口的服务器 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 获取套接字的输出流,用于向服务器发送数据 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 获取套接字的输入流,用于读取服务器返回的数据

第三步,创建socket在服务器的进程:

//cloud.java public void start() throws IOException { serverSocket = new ServerSocket(port); //创建(实例化)一个服务器套接字,监听指定端口 System.out.println("服务器启动,监听端口: " + port); while (true) { Socket clientSocket = serverSocket.accept(); // 等待客户端连接请求,当有客户端连接时返回客户端套接字 System.out.println("客户端已连接: " + clientSocket.getInetAddress()); //在建立连接后,输出日志+客户端ip new ClientHandler(clientSocket).start(); // 创建新线程处理客户端请求 } }

第四步,编写服务器与客户端的数据处理逻辑:

//cloud.java private static class ClientHandler extends Thread { 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 line = in.readLine(); String[] numbers = line.split(","); int a = Integer.parseInt(numbers[0].trim()); int b = Integer.parseInt(numbers[1].trim()); int c = a + b; // 返回计算结果 out.println(c); System.out.println("处理完成: " + a + " + " + b + " = " + c); clientSocket.close(); } catch (Exception e) { // 简化异常处理 } } }
//local.java的sendAndProcessData的后半部分: // 发送数据A和B String requestData = a + "," + b; out.println(requestData); // 接收处理结果C String response = in.readLine(); int result = Integer.parseInt(response); // 关闭资源 in.close(); out.close(); socket.close(); return result; }

最后一步:编写服务器与客户端的主方法:

//local.java public static void main(String[] args) throws IOException { String serverIp = "xxx.xxx.xxx.xxx"; //替换为你的服务器的ip int serverPort = 1234; //注意别忘了放通服务器防火墙 local client = new local(serverIp, serverPort); int a = 10; int b = 20; int c = client.sendAndProcessData(a, b); System.out.println("发送数据: A=" + a + ", B=" + b); System.out.println("接收结果: C=" + c); }
//cloud.java public static void main(String[] args) throws IOException { cloud server = new cloud(1234); // 一定一定要使用与客户端相同的端口号 server.start(); }

我们来试运行一下代码,先将cloud.java上传到你的服务器当中,再在服务器终端上使用java指令运行cloud.java,再在本地运行local.java:

本地终端输出:

服务器终端输出(涂红部分是客户端ip):

可以体会到,原生WebSocket确实在调用上比较麻烦,在下一节中,我们将研究如何使用spring来连接服务器。

附:本节原生WebSocket实现功能的代码:

客户端(local.java):

// local.java package cloudtest; import java.io.*; import java.net.*; public class local { private String serverIp; private int serverPort; public local(String serverIp, int serverPort) { this.serverIp = serverIp; this.serverPort = serverPort; } public int sendAndProcessData(int a, int b) throws IOException { Socket socket = new Socket(serverIp, serverPort); // 创建客户端套接字,连接到指定IP地址和端口的服务器 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 获取套接字的输出流,用于向服务器发送数据 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 获取套接字的输入流,用于读取服务器返回的数据 // 发送数据A和B String requestData = a + "," + b; out.println(requestData); // 接收处理结果C String response = in.readLine(); int result = Integer.parseInt(response); // 关闭资源 in.close(); out.close(); socket.close(); return result; } public static void main(String[] args) throws IOException { String serverIp = "xxx.xxx.xxx.xxx"; int serverPort = 1234; local client = new local(serverIp, serverPort); int a = 10; int b = 20; int c = client.sendAndProcessData(a, b); System.out.println("发送数据: A=" + a + ", B=" + b); System.out.println("接收结果: C=" + c); } }

服务器(cloud.java):

// cloud.java package cloudtest; import java.io.*; import java.net.*; public class cloud { private ServerSocket serverSocket; private int port; public cloud(int port) { this.port = port; } public void start() throws IOException { serverSocket = new ServerSocket(port); //创建(实例化)一个服务器套接字,监听指定端口 System.out.println("服务器启动,监听端口: " + port); while (true) { Socket clientSocket = serverSocket.accept(); // 等待客户端连接请求,当有客户端连接时返回客户端套接字 System.out.println("客户端已连接: " + clientSocket.getInetAddress()); new ClientHandler(clientSocket).start(); // 创建新线程处理客户端请求 } } // 客户端处理线程 private static class ClientHandler extends Thread { 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 line = in.readLine(); String[] numbers = line.split(","); int a = Integer.parseInt(numbers[0].trim()); int b = Integer.parseInt(numbers[1].trim()); int c = a + b; // 返回计算结果 out.println(c); System.out.println("处理完成: " + a + " + " + b + " = " + c); clientSocket.close(); } catch (Exception e) { // 简化异常处理 } } } public static void main(String[] args) throws IOException { cloud server = new cloud(1234); // 使用与客户端相同的端口 server.start(); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:06:13

32、深入探索vi编辑器:参数配置与命令缩写技巧

深入探索vi编辑器:参数配置与命令缩写技巧 在UNIX系统中,vi编辑器是一款功能强大且广泛使用的工具。它提供了丰富的配置选项和灵活的命令缩写功能,能够极大地提高编辑效率。本文将详细介绍vi编辑器的参数配置和命令缩写的相关知识和操作方法。 1. 配置vi参数 vi编辑器拥有…

作者头像 李华
网站建设 2026/4/18 6:58:34

46、UNIX相关知识与组织介绍

UNIX相关知识与组织介绍 1. 推荐组织 在UNIX相关领域,有许多专业组织发挥着重要作用,以下是一些推荐的组织: | 组织名称 | 简介 | 官网 | | ---- | ---- | ---- | | ACM | 世界上历史最悠久、规模最大的教育和科学计算协会。自1947年以来,ACM为信息、思想和发现的交流…

作者头像 李华
网站建设 2026/4/18 9:41:12

buuctf中的ciscn_2019_en_2

首先checksec检查保护机制:-64位程序-开启了栈不可执行保护接下来使用IDA反汇编工具进行分析:发现begin函数,点进去begin函数内部:输入1可用进入encrypt函数,输入2可从主函数看到并没有什么用,3是退出程序这…

作者头像 李华
网站建设 2026/4/8 12:40:32

Kotaemon面试模拟机器人:AI考官训练求职者

Kotaemon面试模拟机器人:AI考官训练求职者 在招聘旺季,一家科技公司HR每天要筛选上百份简历,安排初面、评估候选人表达能力与逻辑思维。传统流程中,每位候选人的初步沟通至少耗时30分钟,而面试官的主观判断差异又常常导…

作者头像 李华
网站建设 2026/4/12 11:07:21

约翰·伯格的长期投资回报预期管理

约翰伯格的长期投资回报预期管理 关键词:约翰伯格、长期投资、回报预期管理、投资理念、指数基金 摘要:本文围绕约翰伯格的长期投资回报预期管理展开深入探讨。首先介绍了约翰伯格及其投资理念的背景,阐述了长期投资回报预期管理的重要性。接着分析了核心概念及相互联系,通…

作者头像 李华
网站建设 2026/4/17 14:36:42

Kotaemon边缘计算部署:Jetson设备运行可行性验证

Kotaemon边缘计算部署:Jetson设备运行可行性验证 在智能制造车间的一台数控机床前,工程师对着语音助手提问:“E-203设备连续报警过热,该怎么处理?”不到两秒,系统便返回了结构化建议:“请立即停…

作者头像 李华