Ⅰ java网络编程从入门到精通(33):非阻塞I/O的缓冲区(Buffer)
如果将同步I/O方式下的数据传输比做数据传输的零星方式(这里的零星是指在数据传输的过程中是以零星的字节方式进行的) 那么就可以将非阻塞I/O方式下的数据传输比做数据传输的集装箱方式(在字节和低层数据传输之间 多了一层缓冲区 因此 可以将缓冲区看做是装载字节的集装箱) 大家可以想象 如果我们要运送比较少的货物 用集装箱好象有点不太合算 而如果要运送上百吨的货物 用集装箱来运送的成本会更低 在数据传输过程中也是一样 如果数据量很小时 使用同步I/O方式会更适合 如果数据量很大时(一般以G为单位) 使用非阻塞I/O方式的效率会更高 因此 从理论上说 数据量越大 使用非阻塞I/O方式的单位成本就会越低 产生这种结果的原因和缓冲区的一些特性有着直接的关系 在本节中 将对缓冲区的一些主要特性进行讲解 使读者可以充分理解缓冲区的概念冲森 并能通过缓冲区来提高程序的执行效率
创建缓冲区
Java提供了七个基本的缓冲区 分别由七个类来扰判拍管理 它们都可以在java nio包中找到 这七个类如下所示
ByteBuffer
ShortBuffer
IntBuffer
CharBuffer
FloatBuffer
DoubleBuffer
LongBuffer
这七个类中的方法类似 只是它们的返回值或参数和相应的简单类型相对应 如ByteBuffer类的get方法返回了byte类型的数据 而put方法需要一个byte类型的参数 在CharBuffer类中的get和put方法返回和传递的数据类型就是char 这七个类都没有public构造方法 因此 它们不能通过new来创建相应的对象实例 这些类都可以通过两种方式来创建相应的对象实例
通过静态方法allocate来创建缓冲区
这七类都有一个静态的allocate方法 通过这个方法可以创建有最大容量限制的缓冲区对象 allocate的定义如下
ByteBuffer类中的allocate方法
(intcapacity)
IntBuffer类中的allocate方法
publicstaticIntBufferallocate(intcapacity)
其他五个缓冲区类中的allocate 方法定义和上面的定义类似 只是返回值的类型是相应的缓冲区缓羡类
allocate方法有一个参数capacity 用来指定缓冲区容量的最大值 capacity的不能小于 否则会抛出一个IllegalArgumentException异常 使用allocate来创建缓冲区 并不是一下子就分配给缓冲区capacity大小的空间 而是根据缓冲区中存储数据的情况来动态分配缓冲区的大小(实际上 在低层Java采用了数据结构中的堆来管理缓冲区的大小) 因此 这个capacity可以是一个很大的值 如 * ( M) allocate的使用方法如下
ByteBufferbyteBuffer=ByteBuffer allocate( );IntBufferintBuffer=IntBuffer allocate( );
在使用allocate创建缓冲区时应用注意 capacity的含义随着缓冲区的不同而不同 如创建字节缓冲区时 capacity指的是字节数 而在创建整型(int)缓冲区时 capacity指的是int型值的数目 如果转换成字数 capacity的值应该乘 如上面代码中的intBuffer缓冲区最大可容纳的字节数是 * = 个
通过静态方法wrap来创建缓冲区
使用allocate方法可以创建一个空的缓冲区 而wrap方法可以利用已经存在的数据来创建缓冲区 wrap方法可以将数组直接转换成相应类型的缓冲区 wrap方法有两种重载形式 它们的定义如下
ByteBuffer类中的wrap方法
publicstaticByteBufferwrap(byte[]array)publicstaticByteBufferwrap(byte[]array intoffset intlength)
IntBuffer类中的wrap方法
publicstaticIntBufferwrap(byte[]array)publicstaticIntBufferwrap(byte[]array intoffset intlength)
其他五个缓冲区类中的wrap 方法定义和上面的定义类似 只是返回值的类型是相应的缓冲区类
在wrap方法中的array参数是要转换的数组(如果是其他的缓冲区类 数组的类型就是相应的简单类型 如IntBuffer类中的wrap方法的array就是int[]类型) offset是要转换的子数组的偏移量 也就是子数组在array中的开始索引 length是要转换的子数组的长度 利用后两个参数可以将array数组中的一部分转换成缓冲区对象 它们的使用方法如下
byte[]myByte=newbyte[]{ };int[]myInt=newint[]{ };ByteBufferbyteBuffer=ByteBuffer wrap(myByte);IntBufferintBuffer=IntBuffer wrap(myInt );
可以通过缓冲区类的capacity方法来得到缓冲区的大小 capacity方法的定义如下
publicfinalintcapacity()
如果使用allocate方法来创建缓冲区 capacity方法的返回值就是capacity参数的值 而使用wrap方法来创建缓冲区 capacity方法的返回值是array数组的长度 但要注意 使用wrap来转换array的字数组时 capacity的长度仍然是原数组的长度 如上面代码中的intBuffer缓冲区的capacity值是 而不是
除了可以将数组转换成缓冲区外 也可以通过缓冲区类的array方法将缓冲区转换成相应类型的数组 IntBuffer类的array方法的定义方法如下(其他缓冲区类的array的定义类似)
publicfinalint[]array()
下面的代码演示了如何使用array方法将缓冲区转换成相应类型的数组
int[]myInt=newint[]{ };IntBufferintBuffer=IntBuffer wrap(myInt );for(intv:intBuffer array()) System out print(v+ );
在执行上面代码后 我们发现输出的结果是 而不是 这说明在将子数组转换成缓冲区的过程中实际上是将整个数组转换成了缓冲区 这就是用wrap包装子数组后 capacity的值仍然是原数组长度的真正原因 在使用array方法时应注意 在以下两种缓冲区中不能使用array方法
只读的缓冲区如果使用只读缓冲区的array方法 将会抛出一个ReadOnlyBufferException异常
使用allocateDirect方法创建的缓冲区
如果调用这种缓冲区中的array方法 将会抛出一个UnsupportedOperationException异常
可以通过缓冲区类的hasArray方法来判断这个缓冲区是否可以使用array方法 如果返回true 则说明这个缓冲区可以使用array方法 否则 使用array方法将会抛出上述的两种异常之一
注意 使用array方法返回的数组并不是缓冲区数据的副本 被返回的数组实际上就是缓冲区中的数据 也就是说 array方法只返回了缓冲区数据的引用 当数组中的数据被修改后 缓冲区中的数据也会被修改 返之也是如此 关于这方面内容将在下一节 读写缓冲区中的数据 中详细讲解
在上述的七个缓冲区类中 ByteBuffer类和CharBuffer类各自还有另外一种方法来创建缓冲区对象
● ByteBuffer类
可以通过ByteBuffer类的allocateDirect方法来创建ByteBuffer对象 allocateDirect方法的定义如下
Direct(intcapacity)
使用allocateDirect方法可以一次性分配capacity大小的连续字节空间 通过allocateDirect方法来创建具有连续空间的ByteBuffer对象虽然可以在一定程度上提高效率 但这种方式并不是平台独立的 也就是说 在一些操作系统平台上使用allocateDirect方法来创建ByteBuffer对象会使效率大幅度提高 而在另一些操作系统平台上 性能会表现得非常差 而且allocateDirect方法需要较长的时间来分配内存空间 在释放空间时也较慢 因此 在使用allocateDirect方法时应谨慎
通过isDirect方法可以判断缓冲区对象(其他的缓冲区类也有isDirect方法 因为 ByteBuffer对象可以转换成其他的缓冲区对象 这部分内容将在后面讲解)是用哪种方式创建的 如果isDirect方法返回true 则这个缓冲区对象是用allocateDirect方法创建的 否则 就是用其他方法创建的缓冲区对象
● CharBuffer类
我们可以发现 上述的七种缓冲区中并没有字符串缓冲区 而字符串在程序中却是最常用的一种数据类型 不过不要担心 虽然java nio包中并未提供字符串缓冲区 但却可以将字符串转换成字符缓冲区(就是CharBuffer对象) 在CharBuffer类中的wrap方法除了上述的两种重载形式外 又多了两种重载形式 它们的定义如下
publicstaticCharBufferwrap(CharSequencecsq)publicstaticCharBufferwrap(CharSequencecsq intstart intend)
其中csq参数表示要转换的字符串 但我们注意到csq的类型并不是String 而是CharSequence CharSequence类Java中四个可以表示字符串的类的父类 这四个类是String StringBuffer StringBuilder和CharBuffer(大家要注意 StringBuffer和本节讲的缓冲区类一点关系都没有 这个类在java lang包中) 也就是说 CharBuffer类的wrap方法可以将这四个类的对象转换成CharBuffer对象
另外两个参数start和end分别是子字符串的开始索引和结束索引的下一个位置 如将字符串 中的 转换成CharBuffer对象的语句如下
CharBuffercb=CharBuffer wrap( );
下面的代码演示了如何使用wrap方法将不同形式的字符串转换成CharBuffer对象
lishixin/Article/program/Java/hx/201311/26505
Ⅱ Java网络编程从入门到精通(23):HTTP消息头字段
专题推荐 网络编程 基础到进阶教程
一 通用头字段
Connection
这个字段只在HTTP 协议中存在 它决定了客户端和服务器进行了一次会话后 服务器是否立即关闭网络连接 在客户端最直接的表现是使用read方法(readLine方法也是一样)读完客户端请求的Web资源后 是否立即返回 (readLine返回null) Connection有两个值 Close和Keep Alive 当使用Connection Close时 和HTTP 协议是一样的 当read方法读完数据时立即返回 而使用Connection Keep Alive时 read方法在读完数据后还要烂局被阻塞一段时间 直接读取数据超时时间过后 还继续往下执行 在上一篇文章中讨论的readHttpResponse(……)方法实现的第 行可以验证Connection的作用 下面让我们来使用HTTP模拟器来做一个实验
( )在HTTP模拟器中输入如下的域名
( )HTTP模拟器中输入如下的HTTP请求信息
GET/HTTP/ 孙唤Host:
( )按两下回车(输入一个空行)后 发送请求消息 并得到如图 如示的HTTP响应消息头
图( )输入y或Y后(在显示响应头后 要立刻输入Y或y) 显示响应消息的内容 在显示完内容后 大约过了 秒钟才进入 host port> 提示符(因为在sendHttpRequest()的实现代码中的 行设置了读取数据超时)
( )在 host port> 提示符下直接按回车 输入最近一次使用的域名和 端口 再次输入如下的HTTP请求
GET/HTTP/ Host: Connection:close
输入完以上的HTTP请求后 重新执行第 步操作 最后在显示HTTP响应消息内容后 直接直入了 host port> 提示符 除了这种方法 将请求的第一行改为GET / HTTP/ 这样也可以无需等待直接结束
通过设置Connection 可以在下载Web资源(如多线程下载工具 Web浏览器等)后 立即断开网络连接 这样可以有效地降低客户机的资源消耗
Date
这个Date头字段描述了请求消息和响应消息被创建的时间 这个字段值是一个HTTP date类型 它的格式必须是GMT(格林尼治)时间 GMT时间是就是北京时间减 小时 下面是Date字段的一个例子
Date:Tue Nov : : GMT
Content Length
指定消息实体的则历凯字节数 在请求消息中POST方法必须使用Content Length来指定请求消息的实体内容的字节数 在响应消息中这个字段值指定了当前HTTP响应所返回的Web资源的字节数
二 HTTP请求消息头字段
Host
Host字段用于指定客户端所访问的资源所在的主机名和端口号 如果端口号等于连接服务器时所使用的端口号 则端口号可以省略 下面是一个使用Host字段的一个例子
Host:
这个字段是必须的 如果HTTP请求不包含这个字段 服务器将返回 (Bad Request)响应状态
Accept
Accept字段头确定客户端可以接收的媒体类型 一般的格式是 */* 或 类型/ 子类型 这个子段头可以传递多个媒体类型 中间用 隔开 如下面是一个Accept的例子
Accept: image/gif image/jpg
如果请求头使用上述的Accept字段值 则服务器端在动态生成网页的IMG头时将首先包含gif格式的图像 如果gif图象不存在 则包含jpg格式的图象
User Agent
这个字段头用于指定客户端是用什么访问的服务器 如果是IE 浏览器 并且本机安装了 net 则User Agent会有如下的值
User Agent:Mozilla/ (patible;MSIE ;WindowsNT ;SV ;Maxthon; NETCLR ; NETCLR ;InfoPath ;InfoPath )
服务器可以通过这个字段检查客户机的浏览器版本 并根据不同的版本来确定向客户端发送的数据
Range
Range字段头通过服务器只传输一部分Web资源 这个字段头可以用来实现断点续传功能 有很多下载工具就是通过这个字段头进行断点续传的 Range字段可以通过三种格式设置要传输的字节范围
( )Range bytes=
传输范围从 到 字节
( )Range bytes=
传输Web资源中第 个字节以后的所有内容
( )Range bytes=
传输最后 个字节
三 HTTP响应消息头字段
Accept Ranges
这个字段说明Web服务器是否支持Range(是否支持断点续传功能) 如果支持 则返回Accept Ranges bytes 如果不支持 则返回Accept Ranges none
Content Range
指定了返回的Web资源的字节范围 这个字段值的格式是
开始字节位置—结束字节位置/Web资源的总字节数
下面是一个使用Content Range的例子
Content Range /
测试
在HTTP模拟器中连接服务器 并输入如下的HTTP请求消息
GET /nokiaguy/HttpSimulator rar HTTP/ Host: Range:bytes=
返回的响应消息头如图 所示
图从上图可以看出 服务器支持断点继传功能 而且还可以验证Content Length的值是当前会话传过来的字节数 并不是Web资源的总的字节数 而Content Range字段值中 / 后面的数才是Web资源总的字节数
Location
lishixin/Article/program/Java/hx/201311/27047
Ⅲ Java网络编程从入门到精通(4):DNS缓存
在通过DNS查找域名的过程中 可能会经过多台中间DNS服务器才能找到指定的域名 因此 在DNS服务器上查找域名是非常昂贵的操作 在Java中为了缓解这个问题 提供了DNS缓存 当InetAddress类第一次使用某个域名(如)创建InetAddress对象后 JVM就会将这个域名和它从DNS上获得的信息(如IP地址)都保存在DNS缓存中 当下一次InetAddress类再使用这个域名时 就直接从DNS缓存里获得所需的信息 而无需再访问DNS服务器
DNS缓存在默认时将永远保留曾经访问过的域名信息 但我们可以修改这个默认值 一般有两种方法可以修改这个默认值
在程序中通过java security Security setProperty方法设置安全属性nel的值(单位 秒) 如下面的代码将缓存超时设为 秒
java security Security setProperty( nel );
设置java security文件中的neorkaddresl属性 假设JDK的安装目录是C jdk 那么java security文件位于c jdk jrelibsecurity目录中 打开这个文件 找到nel属性 并将这个属性值设为相应的缓存超时(单位 秒)
如果将nel属性值设为 那么DNS缓存数据将永远不会释放 下面的代码演示了使用和不使用DNS缓存所产生效果
package mynet;import *;publicclass MyDNS{publicstaticvoidmain(String[]args)throwsException{//args[ ]:本机名args[ ] 缓冲时间if(args length< )return;java security Security setProperty( nel args[ ]);longtime=System currentTimeMillis();InetAddressaddresses []=InetAddress getAllByName(args[ ]);System out println( addresses : +String valueOf(System currentTimeMillis() time)+ 毫秒 );for(InetAddressaddress:addresses )System out println(address);System out print( 按任意键继续 );System in read();time=System currentTimeMillis();InetAddressaddresses []=InetAddress getAllByName(args[ ]);System out println( addresses : +String valueOf(System currentTimeMillis() time)+ 毫秒 );for(InetAddressaddress:addresses )System out println(address);}}
在上面的代码中设置了DNS缓存超时(通过args[ ]参数) 用户可以通过命令行参数将这个值传入MyDNS中 这个程序首先使用getAllByName建立一个InetAddress数组 然后通过System in read使程序暂停 当用户等待一段时间后 可以按任意键继续 并使用同一个域名(args[ ])再建立一个InetAddress数组 如果用户等待的这段时间比DNS缓存超时小 那么无论情况如何变化 addresses 和addresses 数组中的元素是一样的 并且创建addresses 数组所花费的时间一般为 毫秒(小于 毫秒后 Java无法获得更精确的时间)
测试
执行如下命令(将DNS缓存超时设为 秒)
java mynet MyDNS
运行结果 (在 秒之内按任意键)
addresses : 毫秒/ 按任意键继续addresses : 毫秒/
运行结果 (在 秒后按任意键)
addresses : 毫秒/ 按任意键继续addresses : 毫秒/
在上面的测试中可能出现两个运行结果 如果在出现 按任意键继续… 后 在 秒之内按任意键继续后 就会得到运行结果 从这个结果可以看出 addresses 所用的时间为 毫秒 也就是说 addresses 并未真正访问DNS服务器 而是直接从内存中的DNS缓存得到的数据 当在 秒后按任意键继续后 就会得到运行结果 这时 内存中的DNS缓存中的数据已经释放 所以addresses 还得再访问DNS服务器 因此 addresses 的时间是 毫秒(addresses 和addresses 后面的毫秒数可能在不同的环境下的值不一样 但一般情况下 运行结果 的addresses 的值为 或是一个接近 的数 如 运行结果 的addresses 的值一般会和addresses 的值很接近 或是一个远比 大的数 如 )
测试
执行如下命令(ComputerName为本机的计算机名 DNS缓存超时设为永不过期[ ])
java mynet MyDNS ComputerName
运行结果(按任意键继续之前 将 删除)
addresses : 毫秒myuniverse/ myuniverse/ 按任意键继续addresses : 毫秒myuniverse/ myuniverse/
从上面的测试可以看出 将DNS缓存设为永不过期后 无论过多少时间 按任意键后 addresses 任然得到了两个IP地址( 和 ) 而且addresses 的时间是 毫秒 但在这时 已经被删除 因此可以判断 addresses 是从DNS缓存中得到的数据 如果运行如下的命令 并在 秒后按任意键继续后 addresses 就会只剩下一个IP地址( )
java mynet MyDNS ComputerName
如果域名在DNS服务器上不存在 那么客户端在进行一段时间的尝试后(平均为 秒) 就会抛出一个UnknownHostException异常 为了让下一次访问这个域名时不再等待 DNS缓存将这个错误信息也保存了起来 也就是说 只有第一次访问错误域名时才进行 称左右的尝试 以后再访问这个域名时将直接抛出UnknownHostException异常 而无需再等待 秒钟
访问域名失败的原因可能是这个域名真的不存在 也可能是因为DNS服务器或是其他的硬件或软件的临时故障 因此 一般不能将这个域名错误信息一直保留 在Java中可以通过neorkaddresl属性设置保留这些信息的时间 这个属性的默认值是 秒 它也可以通过java security Security setProperty方法或java security文件来设置 下面的代码演示了neorkaddresl属性的用法
package mynet;import *;publicclass MyDNS {publicstaticvoidmain(String[]args)throwsException{java security Security setProperty( neorkaddresl );longtime= ;try{time=System currentTimeMillis();InetAddress getByName( );}catch(Exceptione){System out println( 不存在!address : +String valueOf(System currentTimeMillis() time)+ 毫秒 );}//Thread sleep( );//延迟 秒try{time=System currentTimeMillis();InetAddress getByName( );}catch(Exceptione){System out println( 不存在!address : +String valueOf(System currentTimeMillis() time)+ 毫秒 );}}}
在上面的代码中将neorkaddresl属性值设为 秒 这个程序分别测试了address 和address 访问(这是个不存在的域名 读者可以将其换成任何不存在的域名)后 用了多长时间抛出UnknownHostException异常
运行结果
不存在!address : 毫秒不存在!address : 毫秒
我们从上面的运行结果可以看出 address 使用了 毫秒就抛出了异常 因此 可以断定address 是从DNS缓存里获得了域名不可访问的信息 所以就直接抛出了UnknowHostException异常 如果将上面代码中的延迟代码的注释去掉 那么可能得到如下的运行结果
不存在!address : 毫秒不存在!address : 毫秒
从上面的运行结果可以看出 在第 秒时 DNS缓存中的数据已经被释放 因此 address 仍需要访问DNS服务器才能知道是不可访问的域名
在使用DNS缓存时有两点需要注意
可以根据实际情况来设置nel属性的值 一般将这个属性的值设为 但如果访问的是动态映射的域名(如使用动态域名服务将域名映射成ADSL的动态IP) 就可能产生IP地址变化后 客户端得到的还是原来的IP地址的情况
lishixin/Article/program/Java/hx/201311/11147
Ⅳ Java入门如何学习怎么学好Java开发
Java如今已经是全球编程语言排名第一的语源稿言,运用广泛,前景广阔,而且很多软件的开发都离不开Java,而在以Java为核心的开发领域中,JavaEE程序员的需求量10年来一直居于首位!也正是因为如此很多的小伙伴参加Java培训,当然也有部分小伙伴想要先了解一下,Java到底是什么,怎么可以学好,有个大概的认知才参加Java培训或者Java学习,那么Java入门如何学习?怎么学好Java开发?学习要点是什么?掌握以下内容让Java入门更快,掌握Java更轻松。
一、Java入门如何学习?怎么学好Java开发?Java必备基础知识
1、你需要精通面向对象分析与设计(OOA/OOD)、涉及模式(GOF,J2EEDP)以及综合模式。你应该十分了解UML,尤其是class,object,interaction以及statediagrams。
2、你需要学习JAVA语言的基础知识以及局碰它的核心类库(collections,serialization,streams,networking,multithreading,reflection以及其他)。
3、你应该了解JVM,classloaders,classreflect,以及垃圾回收的基本工作机制等。你应该有能力反编译一个类文件并且明白一些基本的汇编指令。
4、你需要学习java数据库技术,如JDBCAPI并且会使用至少一种persistence/ORM构架,例如Hibernate,JDO,CocoBase,TopLink,InsideLiberator或者iBatis。
5、你应该熟练掌握一种JAVAIDE例如sunOne,netBeans,IntelliJIDEA或者Eclipse。(有些人更喜欢VI或EMACS来编写文件。随便你用什么了:)
6、JAVA(精确的说是有些配置)是冗长的,它需要很多的人工代码(例如EJB),所以你需要熟悉代码生成工具,例如XDoclet等等。
二、Java入门如何学习?怎么学好Java开发?Java学习5大阶段
阶段1:Java设计和编程思想掌握的技能:
精通面向对象思想和Java基础语法;熟练Java异常处理;精通JavaI/O操作;掌握Java多线程操作;精通Jjava集合类的使用;掌握Java网络编程;精通数据库/JDBC的使用。
阶段2:Web前端开发掌握的技能:
掌握html+css+js相关技术;通过H5相关的库快速编写代码;搭桐裂谈建符合大数据要求的界面,使前端+后端+大数据实现三维一体。
阶段3:JavaEE进阶掌握的技能:
掌握Tomcat/Nginx服务器搭建;掌握Jsp&Servlet的使用;精通SSH、SSM两大流行框架的原理及使用。
阶段4:大数据核心知识掌握的技能:
了解hadoop机制原理;了解hadoop集群搭建过程;了解HdfsAPI使用以及mr编程模型;了解hive、hbase、sqoop、flume等组件的使用方法。
阶段5:综合项目掌握的技能:
大型网上商城项目、当日达项目、点餐系统、网上书城、OA办公自动化项目、CRM客户关系管理项目等企业真实综合项目开发能力,达到中高级Java工程师的技术水平。
Java入门如何学习?怎么学好Java开发?这是一个从易到难再到易的过程,需要一步一个脚印去学习,严格意义上说,java是一门较复杂的编程语言,不下苦功,是不可能学到非常好的层次。
同样,学习java为了最快的提升效率和保证你能够学会,还是需要找一家正规专业的培训机构,接受系统化的学习和掌握java实战项目,才能从入门到精通,更快成为一名合格的java工程师。
学Java当然要到17年技术积累的昌平北大青鸟教育,引领行业的技术,一线技术专家,15万家就业合作企业。技术,求职,高薪,你的所有问题都能一站式解决!
2月份Java免费训练营火热报名中,经典Java免费课程限额送,一线技术大牛,为你解析行业前景,就业形势,面试真经,让你一站式成为Java大牛工程师,名额有限,填写下面的表格即可获得试听资格!
Ⅳ Java网络编程从入门到精通(12):使用isReachable方法探测主机是否可以连通
在J SE 中的InetAddress类中增加了一个isReachable方法 可以使用这个方法来探测主机是否可以连通 这个方卖山隐法有两个重载形式 它们的定义如下
publicbooleanisReachable(int唯肆timeout)(NeorkInterfacenetif intttl inttimeout)throwsIOException
第一个重载形式有一个timeout参数 可以通过这个参数设置连接超时(单位 毫秒) 第二个重载形式多了两个参数 netif和ttl 通过netif参数可以使用一个NeorkInterface对象来确定客户端使用哪个网络接口来测试主机的连通性 ttl是指测试连通性过程中的最大连接跃点数(从客户机到达远程主机所经过的最大路由数就是最大连接跃点数 一个路由被称为一个跃点 在Windows网络连接中的 高级TCP/IP设置 对话框最下面可以设置接口跃点数) 如果达到最大连接跃点数 还没找到远程主机 isReachable方法就认为客户机和远程主机之间是不可连通的
isReachable方法是通过连接主机的echo端口来确定客户端中厅和服务端是否可连通 但在Internet上使用这个方法可能会因为放火墙等因素而无法连通远程主机(实际上 远程主机是可以连通的) 因此 isReachable在Internet上并不可靠 但我们可以将isReachable方法应用于局域网中
lishixin/Article/program/Java/hx/201311/27058
Ⅵ Java网络编程从入门到精通(5):使用InetAddress类的getHostName方法获得域
该方法可以得到远程主机的域名 也可以得到本机名 getHostName方法的定义如下
publicStringgetHostName()
下面是三种创建InetAddress对象的方式 在这三种方式中 getHostName返回的值是不同的
使用getLocalHost方法创建InetAddress对象
如果InetAddress对象是用getLocalHost方法创建的 getHostName返回的是本机名 如下面的代码所示
InetAddressaddress=InetAddress getLocalHost();System out println(address getHostName());//输出本机名
使用域名创建InetAddress对象
用域名作为getByName和getAllByName方法的参数调用这两个方法后 系统会自动记住这个域名 当调用getHostName方法时 就无需再访问DNS服务器 而是直接将这个域名返回 如下面的代码所示
InetAddressaddress=InetAddress getByName( );System out println(address getHostName());//无需访问DNS服务器 直接返回域名
使用IP地址创建InetAddress对象
使用IP地址创建InetAddress对象时(getByName getAllByName和getByAddress方法都可以通过IP地址创建InetAddress对象) 并不需要访问DNS服务器 因此 通过DNS服务器查找域名的工作就由getHostName方法来完成 如果这个IP地址不存在或DNS服务器不允许进行IP地址和域名的映射 getHostName方法就直接返回这个IP地址 如下面的代码所示
InetAddressaddress=InetAddress getByName( );System out println(address getHostName());//需要访问DNS服务器才能得到域名InetAddressaddress=InetAddress getByName( );//IP地址不存在System out println(address getHostName());//直接返回IP地址
从上面的三种情况可以看出 只有通过使用IP地址创建的InetAddress对象调用getHostName方法时才访问DNS服务器 在其他情况 getHostName方法并不会访问DNS服务器 而是直接将域名或本机名返回 下面的代码演示了在不同情况下如何使用getHostName方法 并计算了各种情况所需的毫秒数
package mynet;import *;publicclass DomainName{publicstaticvoidmain(String[]args)throwsException{longtime= ;//得到本机名InetAddressaddress =InetAddress getLocalHost();System out println( 本机名 +address getHostName());//直接返回域名InetAddressaddress =InetAddress getByName( );time=System currentTimeMillis();System out print( 直接得到域名 +address getHostName());System out println( 所用时间 +String valueOf(System currentTimeMillis() time)+ 毫秒 );//通过DNS查找域名InetAddressaddress =InetAddress getByName( ); System out println( address : +address );//域名为空time=System currentTimeMillis();System out print( 通过DNS查找域名 +address getHostName());System out println( 所用时间 +String valueOf(System currentTimeMillis() time)+ 毫秒 ); System out println( address : +address );//同时输出域名和IP地址}}
运行结果
本机名 ComputerName直接得到域名 所用时间 毫秒address :/ 通过DNS查找域名 bigip o所用时间 毫秒address :bigip o/
lishixin/Article/program/Java/hx/201311/26413
Ⅶ Java入门如何学习怎么学好Java开发
Java如今已经是全球编程语言排名第一的语言,运用广泛,前景广阔,而且很多软件的开发都离不开Java,而在以Java为核心的开发领域中,JavaEE程序员的需求量10年来一直居于首位!也正是因为如此很多的小伙伴参加Java培训,当然也有部分小伙伴想要先了解一下,Java到底是什么,怎么可以学好,有个大概的认知才参加Java培训或者Java学习,那么Java入门如何学习?怎么学好Java开发?学习要点是什么?掌握以下内容让Java入门更快,掌握Java更轻松。
一、Java入门如何学习?怎么学好Java开发?Java必备基础知识
1、你需要精通面向对象分析与设计(OOA/OOD)、涉及模式(GOF,J2EEDP)以及综合模式。你应该十分了解UML,尤其是class,object,interaction以及statediagrams。
2、你需要学习JAVA语言的基础知识以及它的核心类库(collections,serialization,streams,networking,multithreading,reflection以及其他)。
3、你应该了解JVM,classloaders,classreflect,以及垃圾回收的基本工作机制等。你应该有能力反编译一个类文件并且明白一些基本的汇编指令。
4、你需要学习java数据库技术,如JDBCAPI并且会使用至少一种persistence/ORM构架,例如Hibernate,JDO,CocoBase,TopLink,InsideLiberator或者iBatis。
5、你应该熟练掌握一种JAVAIDE例如sunOne,netBeans,IntelliJIDEA或者Eclipse。(有些人更喜欢VI或EMACS来编写文件。随便你用什么了:)
6、JAVA(精确的说是有些配置)是冗长的,它需要很多的人工代码(例如EJB),所以你需要熟悉代码生成工具,例如XDoclet等等。
二、Java入门如何学习?怎么学好Java开发?Java学习5大阶段
阶段1:Java设计和编程思想掌握的技能:
精通面向对象思想和Java基础语法;熟练Java异常处理;精通JavaI/O操作;掌握Java多线程操作;精通Jjava集合类的使用;掌握Java网络编程;精通数据库/JDBC的使用。
阶段2:Web前端开发掌握的技能:
掌握html+css+js相关技术;通过H5相关的库快速编写代码;搭建符合大数据要求的界面,使前端+后端+大数据实现三维一体。
阶段3:JavaEE进阶掌握的技能:
掌握Tomcat/Nginx服务器搭建;掌握Jsp&Servlet的使用;精通SSH、SSM两大流行框架的原理及使用。
阶段4:大数据核心知识掌握的技能:
了解hadoop机制原理;了解hadoop集群搭建过程;了解HdfsAPI使用以及mr编程模型;了解hive、hbase、sqoop、flume等组件的使用方法。
阶段5:综合项目掌握的技能:
大型网上商城项目、当日达项目、点餐系统、网上书城、OA办公自动化项目、CRM客户关系管理项目等企业真实综合项目开发能力,达到中高级Java工程师的技术水平。
Java入门如何学习?怎么学好Java开发?这是一个从易到难再到易的过程,需要一步一个脚印去学习,严格意义上说,java是一门较复杂的编程语言,不下苦功,是不可能学到非常好的层次。
同样,学习java为了最快的提升效率和保证你能够学会,还是需要找一家正规专业的培训机构,接受系统化的学习和掌握java实战项目,才能从入门到精通,更快成为一名合格的java工程师。
学Java当然要到17年技术积累的昆明北大青鸟教育,引领行业的技术,一线技术专家,15万家就业合作企业。技术,求职,高薪,你的所有问题都能一站式解决!
2月份Java免费训练营火热报名中,经典Java免费课程限额送,一线技术大牛,为你解析行业前景,就业形势,面试真经,让你一站式成为Java大牛工程师,名额有限,填写下面的表格即可获得试听资格!
Ⅷ Java网络编程从入门到精通(15):为什么要使用SocketAddress来管理网络地址
在使用Socket来连接服务器时最简单的方式就是直接使用IP和端口 但Socket类中的connect方法并未提供这种方式 而是使用SocketAddress类来向connect方法传递服务器的IP和端口 虽然这种方式从表面上看要麻烦一些 但它会给我们带来另外一个好处 那就是网络地址的重用
所谓网络地址的重用表现在两个方面
通过建立一个SocketAddress对象 可以在多次连接同一个服务器时使用这个SocketAddress对象
在Socket类中提供了两个方法 getRemoteSocketAddress和getLocalSocketAddress 通过这两个方法可以得到服务器和本机的网络地址 而且所得到的网络地址在相应的Socket对象关闭后任然可以使用 下面是这两个方法的声明
()()
不管在使用Socket类连接服务器时是直接使用IP和端口 还是使用SocketAddress 这两个方法都返回SocketAddress形式的网络地址 当Socket对象未连接时这两个方法返回null 但要注意的是只有在Socket对象未连接时这两个方法才返回null 而当已经连接成功的Socket对象关闭后仍可使用这两个方法得到相应的网络地址
虽然上面曾多次提到SocketAddress 但SocketAddress只是个抽象类 它除了有一个默认的构哪肆肢造方法外 其它的方法都是abstract的 因此 我们必须使用SocketAddress的子类来建立SocketAddress对象 在JDK 中J只为我们提供了IP网络地址的实现类 InetSocketAddress 这个类是从SocketAddress继承的 我们可以通过雹虚如下的方法来建立SocketAddress对象
SocketAddresssocketAddress=newInetSocketAddress(host ip);
下面的代码演示了如何通过SocketAddress来共享网络地址
package mynet;import *;publicclass MySocketAddress{publicstaticvoidmain(String[]args){try{Socketsocket =newSocket( );SocketAddresssocketAddress=socket getRemoteSocketAddress();socket close();李世Socketsocket =newSocket();//socket bind(newInetSocketAddress( ));nnect(socketAddress);socket close(); =(InetSocketAddress)socketAddress;System out println( 服务器域名: +inetSocketAddress getAddress() getHostName());System out println( 服务器IP: +inetSocketAddress getAddress() getHostAddress());System out println( 服务器端口: +inetSocketAddress getPort()); =(InetSocketAddress)socket getLocalSocketAddress();System out println( 本地IP: +inetSocketAddress getAddress() getLocalHost() getHostAddress());System out println( 本地端口: +inetSocketAddress getPort());}catch(Exceptione){System out println(e getMessage());}}}
输出结果
服务器域名
服务器IP
服务器端口
本地IP
本地端口
lishixin/Article/program/Java/hx/201311/26231
Ⅸ Java网络编程从入门到精通(6):使用getCanonicalHostName方法获得主机名
getCanonicalHostName方法和getHostName方法一样 也是得到远程主机的域名 但它们有一个区别 getCanonicalHostName得到的是主机名 而getHostName得到的主机别名 getCanonicalHostName的定义如下
()
在访问某些域名时 getCanonicalHostName方法和getHostName方法的返回值是一样的 这和DNS服务器如何解释主机名和主机别名以及它们的设置有关 如通过创建InetAddress对象后 使用getCanonicalHostName方法和getHostName方法返回的结果都是(有时直接返回IP地址 这可能和IBM的DNS服务器的处理机制有关岩游弊) 如果DNS不允许通过IP地址得到域名 那么这两个方法就会返回IP地址来代替域名 getCanonicalHostName方法可以分三种情况来讨论
使用getLocalHost创建InetAddress对象
在粗族这种情况下getCanonicalHostName方法和getHostName方法得到的都是本机名
使用域名创建InetAddress对象
在这种情况下 getCanonicalHostName方法是否要访问DNS服务器 取决于DNS服务器如何解释主机名和主机别名 也就是说 是否在创建InetAddress对象时就将主机名和主机别名都确定了 在前面已经讲过 使用域名创建InetAddress对象后 调用getHostName方法不会访问DNS服务器 但getCanonicalHostName方法就不一定了 这和DNS服务器的设置有关 如就需要访问DNS服务器 而就不需要访问DNS服务器
使用IP地址创建InetAddress对象
在这种情况下 getCanonicalHostName方法和getHostName方法是完全一样的 也就是说 它们得到的都是主机名 而不是主机别名
之所以要使用主机别名 是因为有时主机名可能比较复杂 如Oracle官方网站的主机名bigip o 因此 为了使用户访问网站更方便 就增加了更简单的主机别名 如 一个主机名可能对应多个主机别名 如也是Oracle的主机别名 在IE的地址栏中输入和都可以访问Oracle官方网站 但我们发现 有很多网站通过主机名无法访问 只有通过一些别名才能访问 如 只能通磨册过和两个主机别名访问 而不能通过它的主机名 cn来访问 这是因为在服务端通过HTTP协议做了限制 这个在前面已经讨论过了 例程 对比了getCanonicalHostName和getHostName方法在不同情况下的输出结果
package mynet;import *;publicclass DomainName{publicstaticvoidoutHostName(InetAddressaddress Strings){System out println( 通过 +s+ 创建InetAddress对象 );System out println( 主机名: +address getCanonicalHostName());System out println( 主机别名: +address getHostName());System out println( );}publicstaticvoidmain(String[]args)throwsException{outHostName(InetAddress getLocalHost() getLocalHost方法 );outHostName(InetAddress getByName( ) );outHostName(InetAddress getByName( ) );outHostName(InetAddress getByName( ) );outHostName(InetAddress getByName( ) );}}
运行结果
通过getLocalHost方法创建InetAddress对象主机名:ComputerName主机别名:ComputerName通过创建InetAddress对象主机名:主机别名:通过创建InetAddress对象主机名: cn主机别名:通过 创建InetAddress对象主机名: cn主机别名: cn通过 创建InetAddress对象主机名: 主机别名:
lishixin/Article/program/Java/hx/201311/26659
Ⅹ 零基础学习Java编程需要知道的十二个步骤!