如何实现java对指定ip和端口接收数据,求源码

如何实现java对指定ip和端口接收数据,求源码,第1张

在客户/服务器通信模式中, 服务器端需要创建监听端口的 ServerSocket, ServerSocket 负责接收客户连接请求。ServerSocket并不能直接向客户端发送数据。

通常做法是,ServerSocket接收到一个连接请求,用accept建立连接:

socket = serverSocketaccept(); //接收客户连接

然后启动一个新的线程来处理和客户端的收发数据的工作

Thread workThread = new Thread(new Handler(socket)); //创建一个工作进程

workThreadstart(); //启动工作进程

使用accept后的Socket去收发数据。

引 言

Java3DAPI是用来开发三维图形和开发基于Web的3D应用程序(applet)的编程接口用于开发三维图形软件的3DAPI(OpenGL、Direct3D)都是基于摄像机模型的思想,即通过调整摄像机的参数来控制场景中的显示对象,而Java3D则提出了一种新的基于视平台的视模型和输入设备模型的技术实现方案,即通过改变视平台的位置、方向来浏览整个虚拟场景它不仅提供了建造和 *** 作三维几何物体的高层构造函数,而且利用这些构造函数还可以建造复杂程度各异的虚拟场景,这些虚拟场景大到宇宙天体,小到微观粒子

Java3D是JavaMediaAPIs中的一部分,可广泛地应用于各种平台,而且用Java3DAPI开发的应用程序和基于Web的3D小应用程序(applet),还可以访问整个Java类,且可以与Internet很好地集成,即如果在浏览器中安装了Java3D的浏览插件,在网上也可浏览Java3D所创建的虚拟场景Java3DAPI还汲取了已有图形APIs的优点,即Java3D的底层图形构造函数不仅综合了底层APIs(Direcrt3D、OpenGL)最好的绘制思想,而且它的高层图形绘制还综合了基于场景图的思想,同时,它又引入了一些通用的图形环境所未考虑的新概念(如3D立体声),这样将有助于提高用户在虚拟场景的沉浸感本文将着重介绍Java3D针对VR应用所提出的基于视模型和输入设备模型的新思想,在此基础上又讨论了如何利用Java3D来开发VR应用程序及其实现方法,并设计实现了一个应用实例

1适于VR应用开发的Java3DAPI众所周知,开发VR应用程序是一件很繁琐的工作,其开发人员必须编写应用程序可能遇到的各种输入和显示设备的接口程序,或者依赖专为VR应用开发而设计的应用程序编程接口(API),且典型的VR应用必须跟踪用户的头部位置和方向,以生成与头部位置方向相一致的虚拟场景图

另外,还需要先跟踪身体的其它部位(手、臂或腿部),然后通过身体各部位在虚拟场景中的虚拟视点与场景中的对象进行交互,而应用程序也必须具有能够利用跟踪输入设备在视点内放置物体,并标明其在生成的三维图象中的位置和方向的功能同时,面向VR的应用程序开发接口(API)必须能支持3D图形生成、处理跟踪器的输入,并能将跟踪信息反馈到图形绘制中

Java3DAPI可自动将头部跟踪器的输入集成到图形生成中,并具有通过访问其它跟踪器信息来控制其它特征的功能,但它是通过一种新的视模型(viewmodel)技术来实现的该视模型是将用户真实的物质环境与计算机生成的虚拟环境相互独立,并建立它们之间的通信桥梁该API也明确定义了用来探测Java3D物体六自由度(6DOF)传感器的返回值,并将其应用于显示场景图中总之,这种新的视模型和输入设备模型可以很方便地将交互式的3D图形应用程序转化为VR应用程序

Java3D视模型

21 新的视模型概念(viewmodel)基于摄像机的视模型是模仿虚拟环境中的摄像机,而不是虚拟环境中人的“替身”,而且它是通过控制摄像机与视点的相关参数来控制所显示的场景,但这种方法,在用户物质环境确定某些视参数的系统中是不合理的,例如在头盔显示器(HMD)系统中,HMD的光学性能就直接确定了应用程序所显示的视域由于不同的HMD有不同的光学特性,因此如果允许终端用户随意改变光学参数显然是不合理的这里视参数的值将随终端用户物质环境的不同而不同,而影响视参数的主要因素有显示器大小、显示器的位置(戴在头上,还是放在桌子上)、三维空间中用户的头部位置、头盔显示器的实际显示视域、每英寸的显示象素等由于Java3D的视模型直接提供了头部跟踪的功能,因而使用户产生了真实存在于虚拟环境中的错觉

Java3D不仅提出了新的基于视平台的视模型概念,同时将其推广到包括显示设备和6DOF外围输入设备(如头部跟踪器等)的接口支持中,而且新的视模型继承了Java的“writeonce,vieweverywhere”本质这意味着由Java3D视模型开发的应用程序或applet可广泛地应用于各种显示环境这种显示环境可以是标准的计算机显示屏、多元显示空间,也可以是头盔显示器Java3D视模型是通过将虚拟环境和物质环境完全独立的方式来实现上述功能的,且该视模型可将虚拟环境中视平台的位置、方向和大小,与Java3D绘制的与视平台位置、方向相一致的虚拟场景相区分一般应用程序控制视平台的位置和方向,而绘制着色系统则依据终端用户的物质环境以及用户在物质环境中的位置和方向来确定显示场景

22 视模型的组成

Java3D视模型由虚拟环境和物质环境两部分组成,其中,虚拟环境由ViewPlatform对象来表示,它是虚拟对象存在的空间;而物质环境则由View对象以及和它相关的对象来表示这里,View对象和它的相关对象就描述了用户所处的显示和 *** 纵输入设备环境虽然视模型将虚拟环境和物质环境相互独立,但可通过一一对应关系来建立两种世界之间相互通信的桥梁,这样将使得终端用户的行为会影响虚拟环境中的对象,同时虚拟环境中的对象行为也会影响终端用户的视点

Java3D可通过几个对象来定义视模型参数这些对象包括View对象及其相关对象、PhysicalBody对象、Canvas3D对象、PhysicalEnvironment对象、Screen3D对象视模型相关的对象(如图1所示)其作用如下:ViewPlatform用来标志场景图中视点位置的节点其父节点则指明了视平台在虚拟环境中的位置、方向和大小View用于指定需要处理场景图的信息Canvas3D定义了Java3D绘制图象的窗口,它提供了Canvas3D在Screen3D对象中的大小、形状和位置信息Screen3D用于描述显示屏幕的物理属性PhysicalBody用于封装那些与物质体相关的参视模型的组成及其相互关系数(如左、右眼的位置等)PhysicalEnvironment用于封装那些与物质体环境相关的参数(如,用于头状物体或头盔式跟踪器的校验信息)

23 虚拟环境中的视平台(ViewPlatform)

鉴于视平台定义了一坐标系统,于是虚拟环境中的原始点和参考点就有了一参考坐标系这里视平台代表与视对象相关的一个点,并充当确定绘制图象的基础图2显示了包括视平台节点场景图的一部分由图2可见,视平台的父节点确定了视平台在虚拟环境中的位置和方向若通过修改与TransformGroup节点相关的Transform3D对象,就可以在虚拟场景中随意移动视平台虽然虚拟环境中可以有许多不同的视平台,但特定的视对象只能与一个视平台相关联,于是在Canvas3D对象中所绘制的场景均来自于一个视平台的视点这样应用程序就可通过修改视平台的TransformGroup节点,在虚拟环境中漫游图2 包括视平台的局部场景图3 Java3D的输入设备模型Java3D除了支持通用的键盘、鼠标输入外,还能给各种不间断的输入设备,如6DOF跟踪设备和 *** 纵杆提供支持由于不同的跟踪输入设备其工作原理不同,因而计算机与其交互的方式也不同为了给不同的6DOF输入设备提供支持,Java3D还提供了一个输入设备接口,而且该输入设备接口还定义了一个抽象的输入设备,虽然用其可以实现对一特定设备的驱动,但输入设备接口的实现必须实现接口所定义的所有方法(如设备开、关、读取 *** 作、状态设置及查询等)Java3D的输入设备列表就用这些方法同特定的设备进行交互

一般Java3D环境中,可能包括许多输入设备,而且这些输入设备不一定是实际的物理设备,也可能是虚拟设备,例如通过软件的方法将鼠标的运动参数转化为6DOF虚拟跟踪球的参数,来模拟虚拟跟踪球的输入由于所有的输入设备都由许多传感器对象组成,因此每一种输入设备都与一定数量的传感器对象相关,且每一种传感器都与其传感器设备6DOF数据的一个数据源相关当输入设备驱动的数据改变时,传感器对象的数据也会相应改变,而且传感器对象由读取传感器对象组成由于缓冲区中记录了各传感器N个读取传感器对象的值,因此可以对传感器数据进行平均,以及对传感器输入值的趋势进行预测等处理,但应用程序的开发并不直接使用输入设备Java3D是通过一个传感器数组将输入设备抽象化,传感器对象数组是物质环境对象的一个子类,该数组是由与输入设备相关的对象指针组成Java程序可以直接从传感器数组中获取传感器的值,并将其用到场景图中,或按任意方式对其进行处理。

24 用Java3D开发VR应用程序利用

Java3D开发的VR应用程序或者applets程序,可建造一个虚拟场景,并能将一个或多个场景图插入到虚拟场景中,虚拟场景由超结构对象集组成,对象集则包括一个世界对象(Universeobject)、一个或多个场所对象(Localeobjects)和按树状结构排列的由节点物体组成的一个或多个场景图(Scenegraphs)该场景图又称为分枝图(Branchgraph),它包括绘制对象节点、光照节点、行为节点和声音节点等,其中,包含内容节点的分枝图称为内容分枝,包含视平台对象的分枝图称为视分枝,视平台对象用来确定用户的位置和方向图3表示了具有多分枝图的Java3D场景图3 应用程序场景图由于这种分枝图只描述了场景所要绘制的对象,并不确定对象的绘制次序,因此图中节点的次序和位置与对象的绘制次序无关,而图中的父节点和子节点的直线路径就唯一确定了子节点的图形范围由于绘制次序的不确定性,因而使得Java3D能横越场景图的任何次序,且它能从左到右,从顶部到底部穿过场景图;或者从右到左,甚至并行遍历整个场景图Java3D的分支图为树状结构,且图中的每一个节点只有一个父节点这样通过辅助的场景图机制就可以实现通用场景图的共享,而且具有连接属性的叶节点可以连接到共享子图分枝图中的节点分为群节点(groupnode)和叶节点(leafnode)两类,其中,群节点按照粘贴的原理来组织场景图单元。

群节点的层次结构图一般群节点包括:BranchGroup、TransformGroup、Switch、OrderGroup、DecalGroup和ShareGroup节点,其中,BranchGroup是分枝图的根节点;而TransformGroup用来指明所有子节点的位置和方向;Switch则用于实现一个或多个子图的转换;OrderGroup用于使它的子节点按照特定的次序绘制;DecalGroup是OrderGroup的一个子集;ShareGroup跟BranchGroup一样,是一个场景图的根节点虽然共享图作为Java3D场景图的一部分从不直接出现,但是连接节点可以引用另外群节点还可以包含各种子节点以及所包含对象的群节点或叶节点这些子节点用一个关联索引属性来允许对特定的子节点进行 *** 作如果没有指明特定的顺序群节点,Java3D还可以按照任意指定的顺序来绘制群节点的子节点虽然叶节点是场景图的抽象类,它没有子节点,但叶节点包括了Java3D的各种信息叶节点由Shape3D、ViewPlatform、Sound、Light以及用户定义的行为节点等组成,Shape3D和ViewPlatform节点在Java3D的视模型和输入模型中扮演着重要的角色,因为它描述了图形系统的两个重要方面,其中,Shape3D描述了场景中对象的几何形状,而ViewPlatform则标定了用户或其视点在虚拟环境中的方向或位置

另外,应用程序还可像 *** 纵分枝图中的任意对象一样,来 *** 纵ViewPlatform,而且应用程序还可平移、旋转和缩放ViewPlatform,即通过改变ViewPlatform的位置和方向,ViewPlatform将随同用户的视点一起移动,来浏览整个虚拟环境虽然ViewPlatform是按照事先规定的路线浏览场景,但不会限制用户视点的移动和向不同方向浏览场景

嵌入式系统或传感器网络的很多应用和测试都需要通过PC机与嵌入式设备或传感器节点进行通信 其中 最常用的接口就是RS 串口和并口(鉴于USB接口的复杂性以及不需要很大的数据传输量 USB接口用在这里还是显得过于奢侈 况且目前除了SUN有一个支持USB的包之外 我还没有看到其他直接支持USB的Java类库) SUN的CommAPI分别提供了对常用的RS 串行端口和IEEE 并行端口通讯的支持 RS C(又称EIA RS C 以下简称RS )是在 年由美国电子工业协会(EIA)联合贝尔系统 调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准 RS 是一个全双工的通讯协议 它可以同时进行数据接收和发送的工作

常见的Java串口包

目前 常见的Java串口包有SUN在 年发布的串口通信API m jar(Windows下) m jar(Linux/Solaris);IBM的串口通信API以及一个开源的实现 鉴于在Windows下SUN的API比较常用以及IBM的实现和SUN的在API层面都是一样的 那个开源的实现又不像两家大厂的产品那样让人放心 这里就只介绍SUN的串口通信API在Windows平台下的使用

串口包的安装(Windows下)

到SUN的网站下载javam win zip 包含的东西如下所示

按照其使用说明(l)的说法 要想使用串口包进行串口通信 除了设置好环境变量之外 还要将win dll复制到 \bin目录下;将m jar复制到 \lib;把m properties也同样拷贝到 \lib目录下 然而在真正运行使用串口包的时候 仅作这些是不够的 因为通常当运行 java MyApp 的时候 是由JRE下的虚拟机启动MyApp的 而我们只复制上述文件到JDK相应目录下 所以应用程序将会提示找不到串口 解决这个问题的方法很简单 我们只须将上面提到的文件放到JRE相应的目录下就可以了

值得注意的是 在网络应用程序中使用串口API的时候 还会遇到其他更复杂问题 有兴趣的话 你可以查看CSDN社区中 关于网页上Applet用javam 读取客户端串口的问题 的帖子

串口API概览

m CommPort

这是用于描述一个被底层系统支持的端口的抽象类 它包含一些高层的IO控制方法 这些方法对于所有不同的通讯端口来说是通用的 SerialPort 和ParallelPort都是它的子类 前者用于控制串行端口而后者用于控这并口 二者对于各自底层的物理端口都有不同的控制方法 这里我们只关心SerialPort

m CommPortIdentifier

这个类主要用于对串口进行管理和设置 是对串口进行访问控制的核心类 主要包括以下方法

l 确定是否有可用的通信端口

l 为IO *** 作打开通信端口

l 决定端口的所有权

l 处理端口所有权的争用

l 管理端口所有权变化引发的事件(Event)

m SerialPort

这个类用于描述一个RS 串行通信端口的底层接口 它定义了串口通信所需的最小功能集 通过它 用户可以直接对串口进行读 写及设置工作

串口API实例

大段的文字怎么也不如一个小例子来的清晰 下面我们就一起看一下串口包自带的例子 SerialDemo中的一小段代码来加深对串口API核心类的使用方法的认识

列举出本机所有可用串口

     void listPortChoices() { CommPortIdentifier portId; Enumeration en = CommPortIdentifier getPortIdentifiers(); // iterate through the ports while (en hasMoreElements()) { portId = (CommPortIdentifier) en nextElement(); if (portId getPortType() == CommPortIdentifier PORT_SERIAL) { System out println(portId getName()); } } portChoice select(parameters getPortName()); }

以上代码可以列举出当前系统所有可用的串口名称 我的机器上输出的结果是 和

串口参数的配置

串口一般有如下参数可以在该串口打开以前配置进行配置

包括波特率 输入/输出流控制 数据位数 停止位和齐偶校验

SerialPort sPort; try { sPort setSerialPortParams(BaudRate Databits Stopbits Parity); //设置输入/输出控制流 sPort setFlowControlMode(FlowControlIn | FlowControlOut); } catch (UnsupportedCommOperationException e) {}

串口的读写

对串口读写之前需要先打开一个串口

     CommPortIdentifier portId = CommPortIdentifier getPortIdentifier(PortName); try { SerialPort sPort = (SerialPort) portId open( 串口所有者名称  超时等待时间); } catch (PortInUseException e) {//如果端口被占用就抛出这个异常 throw new SerialConnectionException(e getMessage()); } //用于对串口写数据 OutputStream os = new BufferedOutputStream(sPort getOutputStream()); os write(int data); //用于从串口读数据 InputStream is = new BufferedInputStream(sPort getInputStream()); int receivedData = is read();

读出来的是int型 你可以把它转换成需要的其他类型

这里要注意的是 由于Java语言没有无符号类型 即所有的类型都是带符号的 在由byte到int的时候应该尤其注意 因为如果byte的最高位是 则转成int类型时将用 来占位 这样 原本是 的byte类型的数变成int型就成了 这是很严重的问题 应该注意避免

串口通信的通用模式及其问题

终于唠叨完我最讨厌的基础知识了 下面开始我们本次的重点 串口应用的研究 由于向串口写数据很简单 所以这里我们只关注于从串口读数据的情况 通常 串口通信应用程序有两种模式 一种是实现SerialPortEventListener接口 监听各种串口事件并作相应处理;另一种就是建立一个独立的接收线程专门负责数据的接收 由于这两种方法在某些情况下存在很严重的问题(至于什么问题这里先卖个关子J) 所以我的实现是采用第三种方法来解决这个问题

事件监听模型

现在我们来看看事件监听模型是如何运作的

l 首先需要在你的端口控制类(例如SManager)加上 implements SerialPortEventListener

l 在初始化时加入如下代码

     try { SerialPort sPort addEventListener(SManager); } catch (TooManyListenersException e) { sPort close(); throw new SerialConnectionException( too many listeners added ); } sPort notifyOnDataAvailable(true);

l 覆写public void serialEvent(SerialPortEvent e)方法 在其中对如下事件进行判断

BI 通讯中断

CD 载波检测

CTS 清除发送

DATA_AVAILABLE 有数据到达

DSR 数据设备准备好

FE 帧错误

OE 溢位错误

OUTPUT_BUFFER_EMPTY 输出缓冲区已清空

PE 奇偶校验错

RI振铃指示

一般最常用的就是DATA_AVAILABLE 串口有数据到达事件 也就是说当串口有数据到达时 你可以在serialEvent中接收并处理所收到的数据 然而在我的实践中 遇到了一个十分严重的问题

首先描述一下我的实验 我的应用程序需要接收传感器节点从串口发回的查询数据 并将结果以图标的形式显示出来 串口设定的波特率是 川口每隔 毫秒返回一组数据(大约是 字节左右) 周期(即持续时间)为 秒 实测的时候在一个周期内应该返回 多个字节 而用事件监听模型我最多只能收到不到 字节 不知道这些字节都跑哪里去了 也不清楚到底丢失的是那部分数据 值得注意的是 这是我将serialEvent()中所有处理代码都注掉 只剩下打印代码所得的结果 数据丢失的如此严重是我所不能忍受的 于是我决定采用其他方法

串口读数据的线程模型

这个模型顾名思义 就是将接收数据的 *** 作写成一个线程的形式:

      public void startReadingDataThread() { Thread readDataProcess = new Thread(new Runnable() { public void run() { while (newData !=  ) { try { newData = is read(); System out println(newData); //其他的处理过程 ……… } catch (IOException ex) { System err println(ex); return; } } readDataProcess start(); }

在我的应用程序中 我将收到的数据打包放到一个缓存中 然后启动另一个线程从缓存中获取并处理数据 两个线程以生产者—消费者模式协同工作 数据的流向如下图所示

这样 我就圆满解决了丢数据问题 然而 没高兴多久我就又发现了一个同样严重的问题 虽然这回不再丢数据了 可是原本一个周期( 秒)之后 传感器节电已经停止传送数据了 但我的串口线程依然在努力的执行读串口 *** 作 在控制台也可以看见收到的数据仍在不断的打印 原来 由于传感器节点发送的数据过快 而我的接收线程处理不过来 所以InputStream就先把已到达却还没处理的字节缓存起来 于是就导致了明明传感器节点已经不再发数据了 而控制台却还能看见数据不断打印这一奇怪的现象 唯一值得庆幸的是最后收到数据确实是 左右字节 没出现丢失现象 然而当处理完最后一个数据的时候已经快 分半钟了 这个时间远远大于节点运行周期 这一延迟对于一个实时的显示系统来说简直是灾难!

后来我想 是不是由于两个线程之间的同步和通信导致了数据接收缓慢呢于是我在接收线程的代码中去掉了所有处理代码 仅保留打印收到数据的语句 结果依然如故 看来并不是线程间的通信阻碍了数据的接收速度 而是用线程模型导致了对于发送端数据发送速率过快的情况下的数据接收延迟 这里申明一点 就是对于数据发送速率不是如此快的情况下前面者两种模型应该还是好用的 只是特殊情况还是应该特殊处理

第三种方法

痛苦了许久(Boss天天催我L)之后 偶然的机会 我听说TinyOS中(又是开源的)有一部分是和我的应用程序类似的串口通信部分 于是我下载了它的 x版的Java代码部分 参考了它的处理方法 解决问题的方法说穿了其实很简单 就是从根源入手 根源不就是接收线程导致的吗 那好 我就干脆取消接收线程和作为中介的共享缓存 而直接在处理线程中调用串口读数据的方法来解决问题(什么 为什么不把处理线程也一并取消 都取消应用程序界面不就锁死了吗所以必须保留)于是程序变成了这样

public byte[] getPack(){ while (true) { // PacketLength为数据包长度 byte[] msgPack = new byte[PacketLength]; for(int i =  ; i < PacketLength; i++){ if( (newData = is read()) !=  ){ msgPack[i] = (byte) newData; System out println(msgPack[i]); } } return msgPack; } }

在处理线程中调用这个方法返回所需要的数据序列并处理之 这样不但没有丢失数据的现象行出现 也没有数据接收延迟了 这里唯一需要注意的就是当串口停止发送数据或没有数据的时候is read()一直都返回 如果一旦在开始接收数据的时候发现 就不要理它 继续接收 直到收到真正的数据为止

结束语

lishixinzhi/Article/program/Java/hx/201311/26605

Android中判断手机是否支持传感器,可以通过SensorManager这个类来获取手机所有的传感器列表,如下代码:

package comexampletestsensor;

import javautilList;

import androidappActivity;

import androidcontentContext;

import androidhardwareSensor;

import androidhardwareSensorManager;

import androidosBundle;

import androidviewView;

import androidviewViewOnClickListener;

import androidwidgetButton;

import androidwidgetTextView;

public class DemoSensorActivity extends Activity {

private Button button;

private TextView show;

private SensorManager sm;

private StringBuffer str;

private List<Sensor> allSensors;

private Sensor s;

@Override

public void onCreate(Bundle savedInstanceState) {

superonCreate(savedInstanceState);

setContentView(Rlayoutmain);

button = (Button) findViewById(Ridbutton);

show = (TextView) findViewById(Ridshow);

buttonsetOnClickListener(new ButtonListener());

sm = (SensorManager) getSystemService(ContextSENSOR_SERVICE);

allSensors = smgetSensorList(SensorTYPE_ALL);// 获得传感器列表

}

class ButtonListener implements OnClickListener {

public void onClick(View v) {

str = new StringBuffer();

strappend("该手机有" + allSensorssize() + "个传感器,分别是:\n");

for (int i = 0; i < allSensorssize(); i++) {

s = allSensorsget(i);

switch (sgetType()) {

case SensorTYPE_ACCELEROMETER:

strappend(i + "加速度传感器");

break;

case SensorTYPE_GYROSCOPE:

strappend(i + "陀螺仪传感器");

break;

case SensorTYPE_LIGHT:

strappend(i + "环境光线传感器");

break;

case SensorTYPE_MAGNETIC_FIELD:

strappend(i + "电磁场传感器");

break;

case SensorTYPE_ORIENTATION:

strappend(i + "方向传感器");

break;

case SensorTYPE_PRESSURE:

strappend(i + "压力传感器");

break;

case SensorTYPE_PROXIMITY:

strappend(i + "距离传感器");

break;

case SensorTYPE_TEMPERATURE:

strappend(i + "温度传感器");

break;

default:

strappend(i + "未知传感器");

break;

}

}

showsetText(str);

}

}

}

是否能够直接访问硬件接口,关键是语言对应的实现和体系结构,而不是语言本身。

现在硬件提供的高级语言接口以及宿主 *** 作系统(若有的话)基本都是基于C/C++的,而Java的实现一般需要背着一个庞大的运行时环境。如果能用Java实现 *** 作系统或者相关接口,再让硬件厂商支持,那么至少理论上是可能的。当然,现实是不合算。

归结到语言的原因主要有两点:

1抽象、实现的复杂性和性能问题。Java在这方面的抽象能力实在太弱了点——比如没有指针算术,没有内建显式内存分配和释放,没有能力直接映射确定地址空间的内存,不能直接支持处理机的调用约定等,会导致使用起来的不便。运行时的实现原理和复杂性制约性能的发挥。而C++其实也需要一些运行时来支持异常和RTTI,虽然禁用这些特性,把C++当C用,可以不太受影响。

2习惯和旧的项目。因为传统,硬件厂商的接口主要是C/汇编,再次才是C++。(这也能说明为什么即便C++能当作C来用,C在这个领域明显更主流。)

ISO C/C++允许没有 *** 作系统支持的独立实现(freestanding implementation)。在这类环境中,硬件提供的接口可以包装为设备的控制寄存器、I/O寄存器等专用存储的状态,映射至volatile限定类型的对象中,使用volatile指针访问(诸如(volatile unsigned int)0x12345678)。通过读写这些对象,被 *** 作的设备就可以和主存或特定设备内存硬件共享存储的内容或发送/接受控制信息。之后这些保持的这些状态由设备中的控制芯片等按需进行一系列处理(如编解码、计算电机转速之类),最终转换为特定的电平信号,用于控制各种设备中各个部件的行为:接通或关闭电源、接受传感器信号、打开无线电、驱动伺服电路等。

在有 *** 作系统支持的宿主实现(hosted implementation)中, *** 作系统一般会提供硬件抽象层(HAL)来对上述接口进行若干公共的抽象和封装,并在此基础上提供自身的API供厂商编写驱动程序。这样的好处很明显,能复用某些设备控制程序的底层实现(例如做成动态库)以便于分发和维护,并能一定程度上保证驱动程序之间以及和 *** 作系统其它部分相互隔离(这样驱动程序bug时系统宕机危险比独立实现的可能小一点,当然因为往往特权等级过高还是比一般程序危险)。具体的接口视具体的系统而定,如POSIX系统的ioctl系统调用、Windows DDK提供的NT内核驱动和WDM驱动API等。

一般来说,上面硬件部分、某些最底层的接口和专用的驱动程序是硬件厂商自己做的,HAL、驱动开发框架和某些通用的设备驱动程序是 *** 作系统厂商提供的,这些基本上用的都是C/C++。剩下的逻辑则全部是上层的应用开发者实现的,只要能调用到底层提供的API,不限于C/C++,Java或者C#什么的都没问题。

以上就是关于如何实现java对指定ip和端口接收数据,求源码全部的内容,包括:如何实现java对指定ip和端口接收数据,求源码、java3d的详细介绍、编程技巧:Java串口通信简介等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9402810.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存