「java从入门到精通笔记」java从入门到精通在线阅读
本篇文章给大家谈谈java从入门到精通笔记,以及java从入门到精通在线阅读对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、Java网络编程从入门到精通(4):DNS缓存
- 2、JAVA初学者看什么书好呢?
- 3、Java网络编程从入门到精通(18):Socket类的getter和setter方法(2)
- 4、高分悬赏帮忙下载文档“韩顺平java从入门到精通视频教程(全94讲)学习笔记整理(齐全)”
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 \jre\lib\security目录中 打开这个文件 找到nel属性 并将这个属性值设为相应的缓存超时(单位 秒)
如果将nel属性值设为 那么DNS缓存数据将永远不会释放 下面的代码演示了使用和不使用DNS缓存所产生效果
package mynet;import *;public class MyDNS{ public static void main(String[] args) throws Exception { // args[ ]: 本机名 args[ ] 缓冲时间 if (args length ) return; java security Security setProperty( nel args[ ]); long time = System currentTimeMillis(); InetAddress addresses [] = InetAddress getAllByName(args[ ]); System out println( addresses : + String valueOf(System currentTimeMillis() time) + 毫秒 ); for (InetAddress address : addresses ) System out println(address); System out print( 按任意键继续 ); System in read(); time = System currentTimeMillis(); InetAddress addresses [] = InetAddress getAllByName(args[ ]); System out println( addresses : + String valueOf(System currentTimeMillis() time) + 毫秒 ); for (InetAddress address : 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 *;public class MyDNS { public static void main(String[] args) throws Exception { java security Security setProperty( neorkaddresl ); long time = ; try { time = System currentTimeMillis(); InetAddress getByName( ); } catch (Exception e) { System out println( 不存在! address : + String valueOf(System currentTimeMillis() time) + 毫秒 ); } //Thread sleep( ); // 延迟 秒 try { time = System currentTimeMillis(); InetAddress getByName( ); } catch (Exception e) { 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地址的情况
lishixinzhi/Article/program/Java/hx/201311/11147
JAVA初学者看什么书好呢?
Java相关书籍知识点比较全面,对初学者系统掌握入门知识很有帮助,下面推荐一些适合相关Java书籍:
1,《Head First Java》java入门书籍
《Head First Java》是本完整的面向对象(object-oriented,OO)程序设计和Java的学习指导。此书是根据学习理论所设计的,让你可以从学习程序语言的基础开始一直到包括线程、网络与分布式程序等项目。最重要的,你会学会如何像个面向对象开发者一样去思考。但如果你真地想要好好地学习Java,你会需要《Head First Java》。这本书可是Amazon编辑推荐的十大好书之一!强烈推荐学习此书,非常适合初学者入门。
2《Java从入门到精通》适合自学者
《Java从入门到精通》这本书主要针对java基础,对于没有学过java的人才说,是一个不错的选择。通过这本书,大家可以从零开始,慢慢来学习,而且实操很多,不会让你看到最后出现只会理论的情况。为什么说培训的人不用看呢?因为这本书上的内容和许多培训机构的书籍有很多重复的地方,所以参加培训的同学就可以不看了。
3.《Thinking in java》(中文名:《Java编程思想》)适合中级自学者和培训者
《Java编程思想》可以说是最经典的java著作,是所有java程序员必备教科书。这本书不管是正在学习还是已经工作许多年的程序员,都可以从这本书中得到你想要的东西。这本书具有教材和工具书的作用,就像一本字典,想知道什么都可以从中查询。虽然这本书很好,但并不建议初学者学习,对于初学者难度较大。
4.《疯狂Java讲义》适合自学者看
《疯狂的讲义》这本书比较适合自学者,内容比较项目化,实操方法很多,如果你想进行java的深入学习,不妨看看这本书。
5.《Java核心技术》最适合报培训班的看
这本书分为两个部分,第一个部分讲的是基础知识,第二个部分讲的是高级特性。由于内容非常有层次,所以非常适合自学和上培训机构的同学学习。尤其对参加培训的同学作用较大,因为一般培训机构讲的非常快,有很多东西没办法及时消化吸收,很多基础和核心的东西就会掌握的不牢固,那么这本书正好弥补了这个缺失。
6.《Java开发实战经典》适合自学者看
这本书比较适合自学者学习,里面有很多小案例,可以边学边练,巩固知识。
Java网络编程从入门到精通(18):Socket类的getter和setter方法(2)
二 用于获得和设置Socket选项的getter和setter方法
Socket选择可以指定Socket类发送和接受数据的方式 在JDK *** 有 个Socket选择可以设置 这 个选项都定义在 SocketOptions接口中 定义如下
public final static int TCP_NODELAY = x ; public final static int SO_REUSEADDR = x ; public final static int SO_LINGER = x ; public final static int SO_TIMEOUT = x ; public final static int SO_SNDBUF = x ; public final static int SO_RCVBUF = x ; public final static int SO_KEEPALIVE = x ; public final static int SO_OOBINLINE = x ;
有趣的是 这 个选项除了第一个没在SO前缀外 其他 个选项都以SO作为前缀 其实这个SO就是Socket Option的缩写 因此 在Java中约定所有以SO为前缀的常量都表示Socket选项 当然 也有例外 如TCP_NODELAY 在Socket类中为每一个选项提供了一对get和set方法 分别用来获得和设置这些选项
TCP_NODELAY
public boolean getTcpNoDelay() throws SocketExceptionpublic void setTcpNoDelay(boolean on) throws SocketException
在默认情况下 客户端向服务器发送数据时 会根据数据包的大小决定是否立即发送 当数据包中的数据很少时 如只有 个字节 而数据包的头却有几十个字节(IP头+TCP头)时 系统会在发送之前先将较小的包合并到软大的包后 一起将数据发送出去 在发送下一个数据包时 系统会等待服务器对前一个数据包的响应 当收到服务器的响应后 再发送下一个数据包 这就是所谓的Nagle算法 在默认情况下 Nagle算法是开启的
这种算法虽然可以有效地改善网络传输的效率 但对于网络速度比较慢 而且对实现性的要求比较高的情况下(如游戏 Telnet等) 使用这种方式传输数据会使得客户端有明显的停顿现象 因此 最好的解决方案就是需要Nagle算法时就使用它 不需要时就关闭它 而使用setTcpToDelay正好可以满足这个需求 当使用setTcpNoDelay(true)将Nagle算法关闭后 客户端每发送一次数据 无论数据包的大小都会将这些数据发送出去
SO_REUSEADDR
public boolean getReuseAddress() throws SocketException public void setReuseAddress(boolean on) throws SocketException
通过这个选项 可以使多个Socket对象绑定在同一个端口上 其实这样做并没有多大意义 但当使用close方法关闭Socket连接后 Socket对象所绑定的端口并不一定马上释放 系统有时在Socket连接关闭才会再确认一下是否有因为延迟面未到达的数据包 这完全是在底层处理的 也就是说对用户是透明的 因此 在使用Socket类时完全不会感觉到
这种处理机制对于随机绑定端口的Socket对象没有什么影响 但对于绑定在固定端口的Socket对象就可能会抛出 Address already in use JVM_Bind 例外 因此 使用这个选项可以避免个例外的发生
package mynet;import *;import java io *;public class Test{ public static void main(String[] args) { Socket socket = new Socket(); Socket socket = new Socket(); try { socket setReuseAddress(true); socket bind(new InetSocketAddress( )); System out println( socket getReuseAddress(): + socket getReuseAddress()); socket bind(new InetSocketAddress( )); } catch (Exception e) { System out println( error: + e getMessage()); try { socket setReuseAddress(true); socket bind(new InetSocketAddress( )); System out println( socket getReuseAddress(): + socket getReuseAddress()); System out println( 端口 第二次绑定成功! ); } catch (Exception e ) { System out println(e getMessage()); } } }}
上面的代码的运行结果如下
socket getReuseAddress():trueerror:Address already in use: JVM_Bindsocket getReuseAddress():true端口 第二次绑定成功!
使用SO_REUSEADDR选项时有两点需要注意
必须在调用bind方法之前使用setReuseAddress方法来打开SO_REUSEADDR选项 因此 要想使用SO_REUSEADDR选项 就不能通过Socket类的构造方法来绑定端口
必须将绑定同一个端口的所有的Socket对象的SO_REUSEADDR选项都打开才能起作用 如在例程 中 socket 和socket 都使用了setReuseAddress方法打开了各自的SO_REUSEADDR选项
SO_LINGER
public int getSoLinger() throws SocketExceptionpublic void setSoLinger(boolean on int linger) throws SocketException
这个Socket选项可以影响close方法的行为 在默认情况下 当调用close方法后 将立即返回 如果这时仍然有未被送出的数据包 那么这些数据包将被丢弃 如果将linger参数设为一个正整数n时(n的值最大是 ) 在调用close方法后 将最多被阻塞n秒 在这n秒内 系统将尽量将未送出的数据包发送出去 如果超过了n秒 如果还有未发送的数据包 这些数据包将全部被丢弃 而close方法会立即返回 如果将linger设为 和关闭SO_LINGER选项的作用是一样的
如果底层的Socket实现不支持SO_LINGER都会抛出SocketException例外 当给linger参数传递负数值时 setSoLinger还会抛出一个IllegalArgumentException例外 可以通过getSoLinger方法得到延迟关闭的时间 如果返回 则表明SO_LINGER是关闭的 例如 下面的代码将延迟关闭的时间设为 分钟
if(socket getSoLinger() == ) socket setSoLinger(true );
SO_TIMEOUT
public int getSoTimeout() throws SocketExceptionpublic void setSoTimeout(int timeout) throws SocketException
这个Socket选项在前面已经讨论过 可以通过这个选项来设置读取数据超时 当输入流的read方法被阻塞时 如果设置timeout(timeout的单位是毫秒) 那么系统在等待了timeout毫秒后会抛出一个InterruptedIOException例外 在抛出例外后 输入流并未关闭 你可以继续通过read方法读取数据
如果将timeout设为 就意味着read将会无限等待下去 直到服务端程序关闭这个Socket 这也是timeout的默认值 如下面的语句将读取数据超时设为 秒
socket setSoTimeout( * );
当底层的Socket实现不支持SO_TIMEOUT选项时 这两个方法将抛出SocketException例外 不能将timeout设为负数 否则setSoTimeout方法将抛出IllegalArgumentException例外
SO_SNDBUF
public int getSendBufferSize() throws SocketExceptionpublic void setSendBufferSize(int size) throws SocketException
在默认情况下 输出流的发送缓冲区是 个字节( K) 这个值是Java所建议的输出缓冲区的大小 如果这个默认值不能满足要求 可以用setSendBufferSize方法来重新设置缓冲区的大小 但最好不要将输出缓冲区设得太小 否则会导致传输数据过于频繁 从而降低网络传输的效率
如果底层的Socket实现不支持SO_SENDBUF选项 这两个方法将会抛出SocketException例外 必须将size设为正整数 否则setSendBufferedSize方法将抛出IllegalArgumentException例外
SO_RCVBUF
public int getReceiveBufferSize() throws SocketExceptionpublic void setReceiveBufferSize(int size) throws SocketException
在默认情况下 输入流的接收缓冲区是 个字节( K) 这个值是Java所建议的输入缓冲区的大小 如果这个默认值不能满足要求 可以用setReceiveBufferSize方法来重新设置缓冲区的大小 但最好不要将输入缓冲区设得太小 否则会导致传输数据过于频繁 从而降低网络传输的效率
如果底层的Socket实现不支持SO_RCVBUF选项 这两个方法将会抛出SocketException例外 必须将size设为正整数 否则setReceiveBufferSize方法将抛出IllegalArgumentException例外
SO_KEEPALIVE
public boolean getKeepAlive() throws SocketExceptionpublic void setKeepAlive(boolean on) throws SocketException
如果将这个Socket选项打开 客户端Socket每隔段的时间(大约两个小时)就会利用空闲的连接向服务器发送一个数据包 这个数据包并没有其它的作用 只是为了检测一下服务器是否仍处于活动状态 如果服务器未响应这个数据包 在大约 分钟后 客户端Socket再发送一个数据包 如果在 分钟内 服务器还没响应 那么客户端Socket将关闭 如果将Socket选项关闭 客户端Socket在服务器无效的情况下可能会长时间不会关闭 SO_KEEPALIVE选项在默认情况下是关闭的 可以使用如下的语句将这个SO_KEEPALIVE选项打开
socket setKeepAlive(true);
SO_OOBINLINE
public boolean getOOBInline() throws SocketException public void setOOBInline(boolean on) throws SocketException
如果这个Socket选项打开 可以通过Socket类的sendUrgentData方法向服务器发送一个单字节的数据 这个单字节数据并不经过输出缓冲区 而是立即发出 虽然在客户端并不是使用OutputStream向服务器发送数据 但在服务端程序中这个单字节的数据是和其它的普通数据混在一起的 因此 在服务端程序中并不知道由客户端发过来的数据是由OutputStream还是由sendUrgentData发过来的 下面是sendUrgentData方法的声明
public void sendUrgentData(int data) throws IOException
虽然sendUrgentData的参数data是int类型 但只有这个int类型的低字节被发送 其它的三个字节被忽略 下面的代码演示了如何使用SO_OOBINLINE选项来发送单字节数据
package mynet;import *;import java io *;class Server{ public static void main(String[] args) throws Exception { ServerSocket serverSocket = new ServerSocket( ); System out println( 服务器已经启动 端口号 ); while (true) { Socket socket = serverSocket accept(); socket setOOBInline(true); InputStream in = socket getInputStream(); InputStreamReader inReader = new InputStreamReader(in); BufferedReader bReader = new BufferedReader(inReader); System out println(bReader readLine()); System out println(bReader readLine()); socket close(); } }}public class Client{ public static void main(String[] args) throws Exception { Socket socket = new Socket( ); socket setOOBInline(true); OutputStream out = socket getOutputStream(); OutputStreamWriter outWriter = new OutputStreamWriter(out); outWriter write( ); // 向服务器发送字符 C outWriter write( hello world\r\n ); socket sendUrgentData( ); // 向服务器发送字符 A socket sendUrgentData( ); // 向服务器发送字符 B outWriter flush(); socket sendUrgentData( ); // 向服务器发送汉字 中 socket sendUrgentData( ); socket sendUrgentData( ); // 向服务器发送汉字 国 socket sendUrgentData( ); socket close(); }}
由于运行上面的代码需要一个服务器类 因此 在加了一个类名为Server的服务器类 关于服务端套接字的使用方法将会在后面的文章中详细讨论 在类Server类中只使用了ServerSocket类的accept方法接收客户端的请求 并从客户端传来的数据中读取两行字符串 并显示在控制台上
测试
由于本例使用了 因Server和Client类必须在同一台机器上运行
运行Server
java mynet Server
运行Client
java mynet Client
在服务端控制台的输出结果
服务器已经启动 端口号 ABChello world中国
在ClienT类中使用了sendUrgentData方法向服务器发送了字符 A ( )和 B ( ) 但发送 B 时实际发送的是 由于sendUrgentData只发送整型数的低字节 因此 实际发送的是 十进制整型 的二进制形式如图 所示
图 十进制整型 的二进制形式
从图 可以看出 虽然 分布在了两个字节上 但它的低字节仍然是
在Client类中使用flush将缓冲区中的数据发送到服务器 我们可以从输出结果发现一个问题 在Client类中先后向服务器发送了 C hello world r n A B 而在服务端程序的控制台上显示的却是ABChello world 这种现象说明使用sendUrgentData方法发送数据后 系统会立即将这些数据发送出去 而使用write发送数据 必须要使用flush方法才会真正发送数据
在Client类中向服务器发送 中国 字符串 由于 中 是由 和 两个字节组成的 而 国 是由 和 两个字节组成的 因此 可分别发送这四个字节来传送 中国 字符串
lishixinzhi/Article/program/Java/hx/201311/26387
高分悬赏帮忙下载文档“韩顺平java从入门到精通视频教程(全94讲)学习笔记整理(齐全)”
韩顺平java从入门到精通视频教程(全94讲)学习笔记整理(齐全).docx
原版文库文档已下载上传,望及时采纳:
点击/我的回答内容右边的"采纳答案"按钮
关于java从入门到精通笔记和java从入门到精通在线阅读的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。