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

[服务器应用开发教程]第二节-使用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(); } }
http://www.cnnetsun.cn/news/137645.html

相关文章:

  • 2025网络安全学习路线 非常详细 推荐学习
  • 测试必知:线上出现BUG,该怎么办!
  • 【C++】学生管理系统设计与实现丨SQLite数据库版本
  • 第55集科立分板机:PCB激光分板机的效率如何
  • 28、UNIX 终端操作与测试实用指南
  • 31、UNIX实用技巧:ASCII表与经典编辑器使用指南
  • 三大限流算法:滑动窗口、令牌桶、漏桶
  • # 深入浅出 Flutter:构建跨平台应用的利器
  • 40、深入了解UNIX系统管理:职责与求职指南
  • stm32毕设本科生任务书指导
  • 效率神器!QuickTextPaste 便携版:快速文本粘贴 + 预设管理全攻略
  • 向量在计算机图形学中的核心应用
  • SelectDB索引实战:从入门到精通,避开那些年我踩过的坑
  • 探秘常见机器人控制运动上位机源码:解锁多种运动算法
  • 9 个降AI率工具,继续教育学生必备!
  • 运用工具Postman快速导出python接口测试脚本
  • 研发管理软件:合规・协同・智能・灵活为汽车部件行业研发管理强力赋能——全星研发管理APQP软件系统功能解析
  • EMS-NT企业微电网能碳管理平台:架构、功能与应用研究
  • 读捍卫隐私10读后总结与感想兼导读
  • OpenAI发布GPT-5.2系列;谷歌推出Gemini Deep Research API:AI领域的最新战况与未来前景
  • 华为云国际站代理商的AS跨境有什么优势呢?
  • NPP 草原:美国中部平原实验牧场(SGS),1939-1990 年,R1
  • CCD相机同步外触发拍照抓拍识别高速脉冲计数器信号采集模块
  • 【网络安全】2025新手如何上手挖漏洞(非常详细)零基础入门到精通,看这篇就够了!
  • BurpSuite渗透测试通关手册,简单几步带你从环境配置到报告生成
  • Python | OpenCV | 图像处理 | 入门实验 | 对比度增强 | 裁剪
  • Apifox:API 接口自动化测试完全指南
  • 正反向代理:网络安全核心技术
  • 别被忽悠了!一文讲透MES管理系统本地部署与SaaS模式的真正底牌
  • 【毕业设计】基于springboot+微信小程序的羽球快讯爱好者平台小程序(源码+文档+远程调试,全bao定制等)