【Java与网络3】Java网络编程之初体验

news2024/11/18 11:18:05

我们平时极少使用Java来直接写网络通信相关的程序,一般都使用Tomcat Web服务或者Netty等框架来帮助我们做,不过呢,要想将技术学到家,我们研究一下基本的网络编程还是非常必要的,这样可以让我们将很多内容融会贯通,更加通透。本文,我们就来练习一下相关内容。

目录

1.感受一下Java的网络编程

2.IP地址的类型

3.使用NetworkInterface类获得网络接口信息

1.感受一下Java的网络编程

在Java的JDK里提供了很多基础的工具来帮助处理网络相关请求。例如我们获取本地或者远程的IP地址可以使用InetAddress来完成,该类是Java中用于描述IP地址的类。它在java.net包中。在Java中分别用Inet4Address和Inet6Address类来描述IPv4和IPv6的地址。这两个类都是InetAddress的子类。由于InetAddress没有public的构造方法,因此,要想创建InetAddress对象,必须得依靠它的四个静态方法。InetAddress可以通过getLocalHost方法得到本机的InetAddress对象,也可以通过getByName、getAllByName和getByAddress得到远程主机的InetAddress对象。
  getLocalHost方法
使用getLocalHost可以得到描述本机IP的InetAddress对象。这个方法的定义如下:
public static InetAddress getLocalHost() throws UnknownHostException
这个方法抛出了一个UnknownHostException异常,因此,必须在调用这个方法的程序中捕捉或抛出这个异常。下面的代码演示了如何使用getLocalHost来得到本机的IP和计算机名。

    public static void test1() throws UnknownHostException {
        InetAddress inetAddress = InetAddress.getLocalHost();
        System.out.println(inetAddress);
    }

此时我们得到这样的一个结果:

***MacBook-Pro.local/127.0.0.1

127.0.0.1 这个就是我们本地的测试地址。

getByName方法
如果我们想获取远端的服务地址该如何做呢?可以使用getByName()来完成,这个方法是InetAddress类最常用的方法。它可以通过指定域名从DNS中得到相应的IP地址。getByName一个String类型参数,可以通过这个参数指定远程主机的域名,它的定义如下:

public static InetAddress getByName(String host) throws UnknownHostException

如果host所指的域名对应多个IP,getByName返回第一个IP。如果本机名已知,可以使用getByName方法来代替getLocalHost。当host的值是localhost时,返回的IP一般是127.0.0.1。如果host是不存在的域名,getByName将抛出UnknownHostException异常,如果host是IP地址,无论这个IP地址是否存在,getByName方法都会返回这个IP地址(因此getByName并不验证IP地址的正确性)。使用getByName的方法如下: 

    public static void test2(String[] args) throws UnknownHostException {
        String host = args[0];
        InetAddress inetAddress = InetAddress.getByName(host);
        System.out.println(inetAddress);
    }

此时我们需要给程序设置一下入参,在idea中的操作如下所示:

此时执行的结果如下:

www.baidu.com/39.156.66.18

这样我们就可以非常方便的获取各类服务器的Id地址了。

我们将这个IP地址输入到浏览器里,也可以打开百度的:

不过有些网站为了安全是不允许直接输入IP地址的。

getAllByName方法
使用getAllByName方法可以从DNS上得到域名对应的所有的IP。这个方法返回一个InetAddress类型的数组。我们还是用上面的百度地址来测试一下:

    public static void test3(String[] args) throws UnknownHostException {
        String host = args[0];
        InetAddress inetAddress[] = InetAddress.getAllByName(host);
        for(InetAddress address:inetAddress){
            System.out.println(address);
        }
    }

得到的结果如下:

www.baidu.com/39.156.66.14
www.baidu.com/39.156.66.18
www.baidu.com/2409:8c00:6c21:1051:0:ff:b0af:279a
www.baidu.com/2409:8c00:6c21:104f:0:ff:b03f:3ae

将前面两个结果进行比较,可以得出一个结论,getByName方法返回的IP地址就是getAllByName方法返回的第一个IP地址。事实上,getByName的确是这样实现的,getByName的实现代码如下:

    public static InetAddress getByName(String host)
        throws UnknownHostException {
        return InetAddress.getAllByName(host)[0];
    }

getByAddress方法
这个方法必须通过IP地址来创建InetAddress对象,而且IP地址必须是byte数组形式。这个我们就不演示了。

通过前面的例子,可以看到,如果我们通过JDK提供的方法可以很方便的获取机器信息的。

大家能想到这个在哪里有用吗?就是如果要为运维设计一套机器监控系统,那这时候自动获取设备的信息就非常必要了。

2.IP地址的类型

IP地址分为普通地址和特殊地址,我们一个机器上往往也会有多种类型的多个地址。我们可以利用InetAddress类提供的方法来确定一个IP地址是否是一个特殊的IP地址。常见的方法有:
(1)isAnyLocalAddress方法
    当IP地址是通配符地址时返回true,否则返回false。这个通配符地址对于拥有多个网络接口(如两块网卡)的计算机非常拥有。使用通配符地址可以允许在服务器主机接受来自任何网络接口的客户端连接。IPv4的通配符地址是0.0.0.0。IPv6的通配符地址是0:0:0:0:0:0:0:0,也可以简写成::。
(2)isLoopbackAddress方法
当IP地址是loopback地址时返回true,否则返回false。loopback地址就是代表本机的IP地址。IPv4的loopback地址的范围是127.0.0.0 ~ 127.255.255.255,也就是说,只要第一个字节是127,就是lookback地址。如127.1.2.3、127.0.200.200都是loopback地址。IPv6的loopback地址是0:0:0:0:0:0:0:1,也可以简写成::1。我们可以使用ping命令来测试lookback地址。如下面的命令行所示:
ping 127.200.200.200
运行结果:

Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

Ping statistics for 127.200.200.200:
        Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
        Minimum = 0ms, Maximum = 0ms, Average = 0ms

 虽然127.255.255.255也是loopback地址,但127.255.255.255在Windows下是无法ping通的。这是因为127.255.255.255是广播地址,在Windows下对发给广播地址的请求不做任何响应,而在其他操作系统上根据设置的不同,可能会得到不同的结果。
(3)isLinkLocalAddress方法
当IP地址是本地连接地址(LinkLocalAddress)时返回true,否则返回false。IPv4的本地连接地址的范围是169.254.0.0 ~ 169.254.255.255。IPv6的本地连接地址的前12位是FE8,其他的位可以是任意取值,如FE88::、FE80::ABCD::都是本地连接地址。
(4)isSiteLocalAddress方法
当IP地址是地区本地地址(SiteLocalAddress)时返回true,否则返回false。IPv4的地址本地地址分为三段:10.0.0.0 ~ 10.255.255.255、172.16.0.0 ~ 172.31.255.255、192.168.0.0 ~ 192.168.255.255。IPv6的地区本地地址的前12位是FEC,其他的位可以是任意取值,如FED0::、FEF1::都是地区本地地址。
(5)isMulticastAddress方法         
当IP地址是广播地址(MulticastAddress)时返回true,否则返回false。通过广播地址可以向网络中的所有计算机发送信息,而不是只向一台特定的计算机发送信息。IPv4的广播地址的范围是224.0.0.0 ~ 239.255.255.255。IPv6的广播地址第一个字节是FF,其他的字节可以是任意值。关于广播地址的详细内容将在以后的章节中讨论。
(6)isMCGlobal方法
    当IP地址是全球范围的广播地址时返回true,否则返回false。全球范围的广播地址可以向Internet中的所有的计算机发送信息。IPv4的广播地址除了224.0.0.0和第一个字节是239的IP地址都是全球范围的广播地址。IPv6的全球范围的广播地址中第一个字节是FF,第二个字节的范围是0E ~ FE,其他的字节可以是任意值,如FFBE::、FF0E::都是全球范围的广播地址。
(7)isMCLinkLocal方法
    当IP地址是子网广播地址时返回true,否则返回false。使用子网的广播地址只能向子网内的计算机发送信息。IPv4的子网广播地址的范围是224.0.0.0 ~ 224.0.0.255。IPv6的子网广播地址的第一个字节是FF,第二个字节的范围是02 ~ F2,其他的字节可以是任意值,如FFB2::、FF02:ABCD::都是子网广播地址。
(8)isMCNodeLocal方法
当IP地址是本地接口广播地址时返回true,否则返回false。本地接口广播地址不能将广播信息发送到产生广播信息的网络接口,即使是同一台计算机的另一个网络接口也不行。所有的IPv4广播地址都不是本地接口广播地址。IPv6的本地接口广播地址的第一个字节是FF,第二个节字的范围是01 ~ F1,其他的字节可以是任意值,如FFB1::、FF01:A123::都是本地接口广播地址。
(9)isMCOrgLocal方法
当IP地址是组织范围的广播地址时返回ture,否则返回false。使用组织范围广播地址可以向公司或企业内部的所有的计算机发送广播信息。IPv4的组织范围广播地址的第一个字节是239,第二个字节不小于192,第三个字节不大于195,如239.193.100.200、239.192.195.0都是组织范围广播地址。IPv6的组织范围广播地址的第一个字节是FF,第二个字节的范围是08 ~ F8,其他的字节可以是任意值,如FF08::、FF48::都是组织范围的广播地址。
(10)isMCSiteLocal方法
当IP地址是站点范围的广播地址时返回true,否则返回false。使用站点范围的广播地址,可以向站点范围内的计算机发送广播信息。IPv4的站点范围广播地址的范围是239.255.0.0 ~ 239.255.255.255,如239.255.1.1、239.255.0.0都是站点范围的广播地址。IPv6的站点范围广播地址的第一个字节是FF,第二个字节的范围是05 ~ F5,其他的字节可以是任意值,如FF05::、FF45::都是站点范围的广播地址。

3.使用NetworkInterface类获得网络接口信息

 我们电脑的网络接口往往有很多种类型,例如本地的、wifi的、各类虚拟的,甚至蓝牙的。我们该如何准确找到我们想要的接口类型呢?Java提供了一个NetworkInterface类,通过这个类可以获得本机所有的物理网络接口和虚拟机等软件利用本机的物理网络接口创建的逻辑网络接口的信息。

NetworkInerface类和InetAddress一样,也没有public的构造方法。因此,必须通过它的两个静态方法来创建NetworkInterface对象。可以使用两种方法来创建NetworkInterface对象:网络接口名(getByName方法)和IP地址(getByInetAddress方法)。
1. getByName方法
这个方法可以通过网络接口名来创建NetworkInterface对象。这个网络接口名并不是计算机名,而是用于标识物理或逻辑网络接口的名字,一般是由操作系统设置的。网络接口名在大多数操作系统上(包括Windows、Linux和Unix)是以eth开头,后面是网络接口的索引号,从0开始。如本机安了三块网卡,那么网络接口名就依次是eth0、eth1和eth2。NetworkInterface对象的toString方法可以返回网络接口的名称、显示名和这个网络接口上绑字的所有IP地址等信息。当网络接口名不存在时,getByName返回null。 

    public static void test4(String[] args) throws Exception {
        NetworkInterface networkInterface = NetworkInterface.getByName(args[0]);
        System.out.println(networkInterface == null);
    }

然后我们使用命令(mac/linux 下使用ifconfig、window下使用ipconfig),找一个已经存在的例如en0,再找一个不存在的例如pp0,来测试就可以判断我们电脑上是否存在指定名称的网络接口名。

 getByInetAddress方法
    除了可以使用网络接口名来得到网络接口的信息,还可以利用getByInetAddress方法来确定一个IP地址属于哪一个网络接口。由于getByInetAddress方法必须使用一个InetAddress对象封装的IP地址来作为参数,因此,在使用getByInetAddress方法之前,必须先创建一个InetAddress对象。但要注意不能使用远程的IP的域名来创建InetAddress对象,否则getByInetAddress将返回null。

    public static void test5(String[] args) throws Exception {
        InetAddress local=InetAddress.getByName(args[0]);
        NetworkInterface networkInterface = NetworkInterface.getByInetAddress(local);
        System.out.println(networkInterface == null);
    }

此时我们在main的入参里输入"127.0.0.1" 或者其他地址,就可以检测是否存在该地址。

同样,我们也可以使用getNetworkInterfaces()参数来获得本机的所有网络接口信息。代码如下:

    public static void test6(String[] args) throws Exception {
        InetAddress local=InetAddress.getByName(args[0]);
        Enumeration<NetworkInterface> networkInterface = NetworkInterface.getNetworkInterfaces();
       while(networkInterface.hasMoreElements()){
           System.out.println(networkInterface.nextElement());
       }
    }

 本文我们介绍了网络编程的基本操作,这些代码本身比较简单 ,请大家自己也手敲一下,感受一下网络编程的魅力。

参考:

本文主要参考李宁(蒙娜丽宁)老师的文章等材料整理而成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1413585.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

把批量M3U8网络视频地址转为MP4视频

在数字媒体时代&#xff0c;视频格式的转换已成为一项常见的需求。尤其对于那些经常处理网络视频的用户来说&#xff0c;将M3U8格式的视频转换为更常见的MP4格式是一项必备技能。幸运的是&#xff0c;现在有了固乔剪辑助手这款强大的工具&#xff0c;这一过程变得异常简单。下面…

单片机学习笔记---矩阵键盘

目录 矩阵键盘的介绍 独立按键和矩阵按键的相同之处&#xff1a; 矩阵按键的扫描 代码演示 代码模块化移植 Keil自定义模板步骤&#xff1a; 代码编写 矩阵键盘就是开发板上右下角的这个模块 这一节的代码是基于上一节讲的LCD1602液晶显示屏驱动代码进行的 矩阵键盘的介…

大数据学习之Flink算子、了解(Source)源算子(基础篇二)

Source源算子&#xff08;基础篇二&#xff09; 目录 Source源算子&#xff08;基础篇二&#xff09; 二、源算子&#xff08;source&#xff09; 1. 准备工作 2.从集合中读取数据 可以使用代码中的fromCollection()方法直接读取列表 也可以使用代码中的fromElements()方…

用户密码网络传输、保存方案分析

大华 1、大华19年的IPC&#xff0c;登录认证接口有两次&#xff0c;第一次请求算法所需数据&#xff0c;第二次传输摘要值&#xff0c;看样子是私有算法。 2、添加用户传输用户密码等敏感数据时&#xff0c;使用"RPAC-256"算法&#xff0c;应该是大华内部的私有算法。…

【从零到一】跑通CATR(二):在并行超算云上使用Cifar-10进行测试

从零到一配环境篇 由于今年要展开大量的编程工作&#xff0c;实验室在用的云计算平台是并行超算云&#xff0c;因此打算在寒假期间先熟悉一下超算云的环境&#xff0c;并从配套的文档和网上的教程开始&#xff0c;从零到一先跑通一个用于音视频分割的模型CATR。 以blog的形式…

docker-compose部署单机ES+Kibana

记录部署的操作步骤 准备工作编写docker-compose.yml启动服务验证部署结果 本次elasticsearch和kibana版本为8.2.2 使用环境&#xff1a;centos7.9 本次记录还包括&#xff1a;安装elasticsearch中文分词插件和拼音分词插件 准备工作 1、创建目录和填写配置 mkdir /home/es/s…

Vue3中的ref和shallowRef、reactive和shallowReactive

一&#xff1a;ref、reactive简介 ref和reactive是Vue3中定义响应式数据的一种方式。ref通常用来定义基础类型数据。reactive通常用来定义复杂类型数据。 二、shallowRef、shallowReactive简介 shallowRef和shallowReactive是Vue3中定义浅层次响应式数据的方式 三、Api使用对比…

【寒假每日一题·2024】AcWing 5307. 小苹果(补)

文章目录 一、题目1、原题链接2、题目描述 二、解题报告1、思路分析2、时间复杂度3、代码详解 三、知识风暴 一、题目 1、原题链接 5307. 小苹果 2、题目描述 二、解题报告 1、思路分析 思路参考y总&#xff1a;y总讲解视频 &#xff08;1&#xff09;根据题目可以分析出&…

中小型企业机房设计部署方案

我对接参与过至少十几个分公司和总部的机房设计&#xff0c;结合十几年实际工作管理经验&#xff0c;归纳设计了以下这个机房方案&#xff0c;这个机房最大化利用了空间的同时&#xff0c;最大化设计了各方面的冗余。 机房包含了UPS隔离&#xff0c;噪音隔离&#xff0c;功率冗…

SpringBoot之分页查询的使用

背景 在业务中我们在前端总是需要展示数据&#xff0c;将后端得到的数据进行分页处理&#xff0c;通过pagehelper实现动态的分页查询&#xff0c;将查询页数和分页数通过前端发送到后端&#xff0c;后端使用pagehelper&#xff0c;底层是封装threadlocal得到页数和分页数并动态…

2. MySQL 多实例

重点&#xff1a; MySQL 的 三种安装方式&#xff1a;包安装&#xff0c;二进制安装&#xff0c;源码编译安装。 MySQL 的 基本使用 MySQL 多实例 DDLcreate alter drop DML insert update delete DQL select 2.5&#xff09;通用 二进制格式安装 MySQL 2.5.1&#xff…

深入理解ZooKeeper分布式锁

第1章&#xff1a;引言 分布式系统&#xff0c;简单来说&#xff0c;就是由多台计算机通过网络相连&#xff0c;共同完成任务的系统。想象一下&#xff0c;咱们平时上网浏览网页、看视频&#xff0c;背后其实都是一大堆服务器在协同工作。这些服务器之间需要协调一致&#xff…

拥有大规模犯罪联盟链的网络攻击中心

VexTrio 是一个网络犯罪集团&#xff0c;其历史至少可以追溯到 2017 年&#xff0c;该集团涉嫌利用复杂的字典域生成算法 (DDGA) 进行邪恶活动。 他们的恶意活动包括诈骗、风险软件、间谍软件、广告软件、隐匿垃圾程序 (PUP) 和露骨内容&#xff0c;其中 2022 年发生的一次引…

【广度优先搜索】【拓扑排序】【C++算法】913. 猫和老鼠

作者推荐 【动态规划】【map】【C算法】1289. 下降路径最小和 II 本文涉及知识点 广度优先搜索 拓扑排序 逆推 LeetCode913. 猫和老鼠 两位玩家分别扮演猫和老鼠&#xff0c;在一张 无向 图上进行游戏&#xff0c;两人轮流行动。 图的形式是&#xff1a;graph[a] 是一个列…

067:Vue2 + vite 开发环境的搭建(含源文件包,运行即可)

第067个 查看专栏目录: VUE 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使用&#xff0c;computed&#xff0c;watch&am…

【机组】单元模块实验的综合调试与驻机键盘和液晶显示器的使用方式

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《机组 | 模块单元实验》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 1. 综合实验的调试 1.1 实验…

YOLOv8改进 | Conv篇 | 结合Dual思想利用HetConv创新一种全新轻量化结构CSPHet(参数量下降70W)

一、本文介绍 本文给大家带来的改进机制是我结合Dual的思想利用HetConv提出一种全新的结构CSPHet,我们将其用于替换我们的C2f结构,可以将参数降低越75W,GFLOPs降低至6.6GFLOPs,同时本文结构为我独家创新,全网无第二份,非常适合用于发表论文,该结构非常灵活,利用Dual卷…

调用阿里通义千问大语言模型API-小白新手教程-python

阿里大语言模型通义千问API使用新手教程 最近需要用到大模型&#xff0c;了解到目前国产大模型中&#xff0c;阿里的通义千问有比较详细的SDK文档可进行二次开发,目前通义千问的API文档其实是可以进行精简然后学习的,也就是说&#xff0c;是可以通过简单的API调用在自己网页或…

【GitHub项目推荐--推荐一个开源的任务管理工具(仿X书/X钉)】【转载】

推荐一个开源的任务管理工具&#xff0c;该工具会提供各类文档协作功能、在线思维导图、在线流程图、项目管理、任务分发、即时 IM&#xff0c;文件管理等等。该开源项目使用到 Vue、Element-UI、ECharts 等技术栈。 开源地址&#xff1a;www.github.com/kuaifan/dootask 预览地…

ES的一些名称和概念总结

概念 先看看ElasticSearch的整体架构&#xff1a; 一个 ES Index 在集群模式下&#xff0c;有多个 Node &#xff08;节点&#xff09;组成。每个节点就是 ES 的Instance (实例)。每个节点上会有多个 shard &#xff08;分片&#xff09;&#xff0c; P1 P2 是主分片, R1 R2…