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

网络编程---Java飞机大战联机

解析服务器端代码

代码是放在app/lib下的src下的main/java,而与之前放在app/src/main下路径不同

Main函数

Main函数里只放着创建MyServer类的一行

public static void main(String args[]){new MyServer();}

MyServer构造函数

1.获取本机IP地址

//获取本机IP地址InetAddress addr = InetAddress.getLocalHost();System.out.println("local host:" + addr);

2.创建serverSocket(创建服务器套接字并绑定到一个端口上)

//创建server socketServerSocket serverSocket = new ServerSocket(9999);System.out.println("listen port 9999");

3.accept方法监听等待

//等待客户端连接while(true){System.out.println("waiting client connect");//从连接请求队列中取出一个客户的连接请求,然后创建与客户连接的Socket对象,并将它返回// 如果队列中没有连接请求,accept()方法就会一直等待,直到接收到了连接请求才返回Socket socket = serverSocket.accept();//连接成功,返回socket对象System.out.println("accept client connect" + socket);new Thread(new Service(socket)).start();}

4.监听成功,创建线程进行通信(上一步while循环内最后一行)

创建线程进行通信

  • 线程构造函数内,new数据传输通道
 class Service implements Runnable{private Socket socket;private BufferedReader in = null;public Service(Socket socket){this.socket = socket;try{//InputStreamReader把字节流转化成字符流//BufferedReader用于读取字符流。它继承自Reader类,提供了按行读取文件的功能in = new BufferedReader(new InputStreamReader(socket.getInputStream()));}catch (IOException ex){ex.printStackTrace();}}
  • 重写的run函数内,用一个while来不断读入客户端传来的流(用BufferedReader)
@Overridepublic void run() {System.out.println("wait client message " );try {while ((content = in.readLine()) != null) {//从socket连接读取到bye标识客户端发出断开连接请求if(content.equals("bye")){System.out.println("disconnect from client,close socket");//关闭socket输入输出流socket.shutdownInput();socket.shutdownOutput();socket.close();   //关闭socket连接break;}else {//从socket连接读取到的不是断开连接请求,则像客户端发信息this.sendMessge(socket);}}} catch (Exception ex) {ex.printStackTrace();}}
  • 如何sendMessage:用PrintWriter
public void sendMessge(Socket socket) {PrintWriter pout = null;try{String message = "hello,client!";System.out.println("messge to client:" + message);//OutputStreamWriter:将字符流转换为字节流//BufferedWriter:是缓冲字符输出流//PrintWriter:字符类型的打印输出流pout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"utf-8")),true);//利用输出流输出数据pout.println(message);}catch (IOException ex){ex.printStackTrace();}}

解析客户端代码

1.与服务器的连接

NetConn netConn = new NetConn(handler);

2.与服务器的信息交流

其中的writer在与服务器进行连接会把它进行赋值,它是获得了socket输出流的PrintWriter,把信息给到服务器。(注:接收服务器的信息是在netConn线程的run方法里用了一个while)

new Thread(){@Overridepublic void run(){Log.i(TAG, "send message to server");writer.println("hello,server");}}.start();

NetConn是一个线程

在重写的 run 方法里

1.创建socket并连接对象

//创建socket对象socket = new Socket();//connect,要保证服务器已启动socket.connect(new InetSocketAddress("10.0.2.2",9999),5000);

2.获取socket的输入输出流

//获取socket输入输出流in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"utf-8")),true);Log.i(TAG,"connect to server");

3.再建一个线程,接收服务器的数据

//接收服务器返回的数据Thread receiveServerMsg =  new Thread(){@Overridepublic void run(){String fromserver = null;try{while((fromserver = in.readLine())!=null){//发送消息给UI线程Message msg = new Message();msg.what = 1;msg.obj = fromserver;toClientHandler.sendMessage(msg);}}catch (IOException ex){ex.printStackTrace();}}};

感觉hander像个快递员???把在服务器接收数据线程里,接收到的东西,打包成message,通过sendMessage函数,发给UI线程(就是那些Activity),进行相应操作。

以下是MainActivity内的Handler

handler = new Handler(Looper.getMainLooper()){//当数据处理子线程更新数据后发送消息给UI线程,UI线程更新UI@Overridepublic void handleMessage(Message msg){if(msg.what == 1){txt.setText(msg.obj.toString());}}};

相关文章:

网络编程---Java飞机大战联机

解析服务器端代码 代码是放在app/lib下的src下的main/java,而与之前放在app/src/main下路径不同 Main函数 Main函数里只放着创建MyServer类的一行 public static void main(String args[]){new MyServer();} MyServer构造函数 1.获取本机IP地址 //获取本机IP地…...

一个简单的Oracle函数

CREATE OR REPLACE FUNCTION getyj_zhibiao_value(p_name IN varchar2, p_index IN varchar2) RETURN NUMBER IS -- 定义返回的指标值变量 v_result NUMBER; -- 定义临时变量来存储查询到的指标值 v_index1 VARCHAR2(50); v_index2 VARCHAR2(50); …...

word中根据上级设置下级编号

如上级是3.13.4,如下图 现在想设置下级编码跟随上级逐级显示成3.13.4.1 则在标题功能说明这点击顶部菜单栏的编号按钮,如下图 然后,选择自定义编号-自定义列表-自定义按钮 然后重点是编号格式这一栏,需要手动填写下前三级的编号&…...

【康复学习--LeetCode每日一题】2786. 访问数组中的位置使分数最大

题目描述&#xff1a; 给你一个下标从 0 开始的整数数组 nums 和一个正整数 x 。 你一开始 在数组的位置 0 处&#xff0c;你可以按照下述规则访问数组中的其他位置&#xff1a; 如果你当前在位置 i &#xff0c;那么你可以移动到满足 i < j 的 任意 位置 j 。 对于你访问的…...

bash和sh区别

bash 和 sh 是两种常用的 Unix Shell&#xff0c;它们有一些区别&#xff0c;特别是在功能和兼容性方面。以下是一些主要的区别&#xff1a; 1. **历史与实现**&#xff1a; - sh&#xff08;Bourne Shell&#xff09;是第一个 Unix Shell&#xff0c;最初由 Stephen Bourn…...

Git 代码管理规范 !

分支命名 master 分支 master 为主分支&#xff0c;也是用于部署生产环境的分支&#xff0c;需要确保master分支稳定性。master 分支一般由 release 以及 hotfix 分支合并&#xff0c;任何时间都不能直接修改代码。 develop 分支 develop 为开发环境分支&#xff0c;始终保持最…...

MGRS坐标

一 概述 MGRS坐标系统&#xff0c;即军事格网参考系统&#xff0c;是北约(NATO)军事组织使用的标准坐标系统。它基于UTM&#xff08;通用横向墨卡托&#xff09;系统&#xff0c;并将每个UTM区域进一步划分为100km100km的小方块。这些方块通过两个相连的字母标识&#xff0c;其…...

FreeRTOS简单内核实现4 临界段

文章目录 0、思考与回答0.1、思考一0.2、思考二0.3、思考三 1、关中断1.1、带返回值1.2、不带返回值 2、开中断3、临界段4、应用 0、思考与回答 0.1、思考一 为什么需要临界段&#xff1f; 有时候我们需要部分代码一旦这开始执行&#xff0c;则不允许任何中断打断&#xff0…...

Scala的字符串插值

Scala的字符串插值 期待您的关注 ☀Scala学习笔记 目录 Scala的字符串插值 1. s插值器&#xff1a; 2. f插值器&#xff1a; 3. raw插值器&#xff1a; 在Scala中&#xff0c;字符串插值是一种方便的方式&#xff0c;可以在字符串中插入变量或表达式的值。Scala支持三种类型…...

EasyGBS服务器和终端配置

服务器配置 修改easygbs.ini sip/host为本机IP&#xff0c;否则终端能登录&#xff0c;无法视频。 [sip] host192.168.3.190 终端用于登录的用户名和密码 default_usertest default_passwordtest1234 default_guest_userguest default_guest_passwordtest1234终端配置 关…...

git配置2-不同的代码托管平台配置不同的ssh key

1. 配置单个ssh key 1.1. 原理1.2. 生成 ssh key1.3. 代码托管平台配置公钥 2. 配置多个ssh key 2.1. 应用场景2.2. 生成两个不同的key2.3. 修改config文件2.4. 配置代码托管平台2.5. 测试是否成功 1. 配置单个ssh key 1.1. 原理 使用ssh命令行工具&#xff08;git安装成功…...

【CT】LeetCode手撕—102. 二叉树的层序遍历

目录 题目1-思路2- 实现⭐102. 二叉树的层序遍历——题解思路 3- ACM实现3-1 二叉树构造3-2 整体实现 题目 原题连接&#xff1a;102. 二叉树的层序遍历 1-思路 1.借助队列 Queue &#xff0c;每次利用 ①while 循环遍历当前层结点&#xff0c;②将当前层结点的下层结点放入 …...

Flink 命令行提交、展示和取消作业

Apache Flink 是一个流处理和批处理的开源框架&#xff0c;用于在分布式环境中执行无边界和有边界的数据流。你可以使用 Flink 的命令行界面&#xff08;CLI&#xff09;来提交、展示和取消作业。 提交作业 使用 Flink CLI 提交作业的命令格式通常如下&#xff1a; ./bin/fl…...

STM32单片机选型方法

一.STM32单片机选型方法 1.首先要确定需求&#xff1a; 性能需求&#xff1a;根据应用的复杂度和性能要求&#xff0c;选择合适的CPU性能和主频。 内存需求&#xff1a;确定所需的内存大小&#xff0c;包括RAM和Flash存储空间。 外设需求&#xff1a;根据应用所需的功能&…...

gsap动画库的实践

先看效果&#xff1a; gsap动画库 安装插件&#xff1a;npm install gsap <template><div><h1 style"text-align: left">gsap的用法</h1><h1 style"text-align: left">https://gsap.com/resources/get-started</h1>&…...

LeetCode | 387.字符串中的第一个唯一字符

这道题可以用字典解决&#xff0c;只需要2次遍历字符串&#xff0c;第一次遍历字符串&#xff0c;记录每个字符出现的次数&#xff0c;第二次返回第一个出现次数为1的字符的下标&#xff0c;若找不到则返回-1 class Solution(object):def firstUniqChar(self, s):""…...

textarea 中的内容在word中显示换行不起作用

js文本换行在word显示 在JavaScript中&#xff0c;处理文本换行以确保它在Word中正确显示&#xff0c;通常需要将文本中的换行符转换为Word可识别的格式。在HTML中&#xff0c;换行通常是通过<br>标签来实现的&#xff0c;而在Word中&#xff0c;换行通常由段落标签<…...

Python 测试用例

在Python中编写测试用例通常使用unittest模块&#xff0c;这是Python标准库的一部分&#xff0c;专门用于编写和运行测试。下面是一个简单的测试用例的例子&#xff0c;展示了如何使用unittest模块来测试一个函数。 假设我们有一个简单的函数&#xff0c;用于计算两个数的和&a…...

树莓派等Linux开发板上使用 SSD1306 OLED 屏幕,bullseye系统 ubuntu,debian

Raspberry Pi OS Bullseye 最近发布了,随之而来的是许多改进,但其中大部分都在引擎盖下。没有那么多视觉差异,最明显的可能是新的默认桌面背景,现在是大坝或湖泊上的日落。https://www.the-diy-life.com/add-an-oled-stats-display-to-raspberry-pi-os-bullseye/ 通过这次操…...

SpringBoot3 整合 Mybatis 完整版

本文记录一下完整的 SpringBoot3 整合 Mybatis 的步骤。 只要按照本步骤来操作&#xff0c;整合完成后就可以正常使用。1. 添加数据库驱动依赖 以 MySQL 为例。 当不指定 依赖版本的时候&#xff0c;会 由 springboot 自动管理。 <dependency><groupId>com.mysql&l…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...