根据传输数据的方式这里把I/O流分为:
1.基于磁盘操作的I/O接口:File
2.基于网络操作的I/O接口:socket
下面看一个典型的socket连接实例
服务器端:
public class ThreadSocketServer {
/** 服务器端口 **/
public static final int PORT = 8189;
public static void main(String[] args) {
int i = 1;
try {
ServerSocket s = new ServerSocket(PORT);
System.out.println("Listening on port: " + PORT);
while (true) {
Socket incoming = s.accept();
System.out.println("Spawning" + i);
Runnable r = new ThreadedEchoHandler(incoming);
Thread t = new Thread(r);
t.start();
i++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ThreadedEchoHandler implements Runnable {
private Socket incoming;
public ThreadedEchoHandler(Socket i) {
incoming = i;
}
@Override
public void run() {
try {
try {
OutputStream outStream = incoming.getOutputStream();
PrintWriter out = new PrintWriter(outStream, true);
out.println("Hello!");
} finally {
incoming.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端:
public class SocketClient {
/** 客户端尝试连接的次数 **/
public static final int CONNECT_UNM = 5000;
/** 服务器端IP **/
public static final String SERVER_IP = "127.0.0.1";
public static void main(String[] args) {
for (int i = 0; i < CONNECT_UNM; i++) {
final int temp=i+1;
new Thread(new Runnable() {
@Override
public void run() {
Socket s = null;
try {
s = new Socket(SERVER_IP, ThreadSocketServer.PORT);
System.out.println("第" + temp + "尝试连接--分配的本地端口:"
+ s.getLocalPort());
InputStream inStream = s.getInputStream();
Scanner in = new Scanner(inStream);
System.out.println(in.nextLine());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
}
}
}
}).start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
从上面的例子中我们了解了以下几个关键点:
1. 连接->传输数据->关闭连接 是一个短连接的实例
2. 在客户端我们指定了一个连接数5000,当我们在本地的xp下进行测试时,当连接达到3970左右时,异常java.net.BindException: Address already in use: connect
原因:在Java网络编程(一)中我们了解到:动态端口的分配范围为 1024-5000 ,也就是说默认情况下,客户端最多可以同时发起3977 个Socket 连接。有人会问我们不是在每次连接的时候都关闭了连接,应该会释放掉可用的端口啊?
备注:关闭TCP连接
我们要知道当我们关闭socket的时候我们要知道TCP连接并不是马上就能关闭。TCP协议有一个优雅的关闭(graceful close)机制,以保证应用程序在关闭连接时不必担心正在传输的数据会丢失。
TCP还是使用了包括Time-Wait状态在内的多种机制对其进行防范。Time-Wait状态用于保证每个TCP连接都在一段平静时间内结束,这期间不会有数据发送。平静时间的长度应该等于分组报文在网络上存留的最长时间的两倍。因此,当一个连接完全结束(即套接字数据结构离开Time-Wait状态并被删除),并为同样一对地址上的新连接清理道路后,就不会再有旧实例发送的消息还存留在网络中。实际上,平静时间的长度要依赖于具体实现,因为没有机制能真正限制分组报文在网络上能够延迟的时间。通常使用的时间范围是4分钟减到30秒,或更短。
Time-Wait状态最重要的作用是,只要底层套接字数据结构还存在,就不允许在相同的本地端口上关联其他套接字。尤其是试图使用该端口创建新的Socket实例时,将抛出IOException异常。
所以在最短的30s内我们已经执完了我们的循环,最后导致客户端的动态端口不可用。
3. 阻塞与非阻塞
阻塞与非阻塞主要是从 CPU 的消耗上来说的,阻塞就是 CPU 停下来等待一个慢的操作完成 CPU 才接着完成其它的事。非阻塞就是在这个慢的操作在执行时 CPU 去干其它别的事,等这个慢的操作完成时,CPU 再接着完成后续的操作。虽然表面上看非阻塞的方式可以明显的提高 CPU 的利用率,但是也带了另外一种后果就是系统的线程切换增加。增加的 CPU 使用时间能不能补偿系统的切换成本需要好好评估。
我们知道在jdk1.4之前只有阻塞I/O,如果我们所有客户端的连接都放在一个线程中,这样的话,很容易造成一个用户出现问题(I/O阻塞)其他用户受到影响。所有一种常用的方式就是:在服务器端为每个到来的客户端都开通了一个线程,这样的话出现阻塞时只是一个线程阻塞而不会影响其它线程工作,还有为了减少系统线程的开销,采用线程池的办法来减少线程创建和回收的成本。但是这样的话也存在问题:系统的线程切换增加。
针对以上的问题在jdk1.4以后提供了一个新的概念:nio,有效解决了多线程服务器存在的线程开销问题……………..待续
分享到:
相关推荐
3. **NIO(非阻塞I/O)**:Java 1.4引入了`java.nio`包,提供了非阻塞I/O操作,提高了网络和文件系统I/O性能,尤其适合高并发场景。 4. **集合框架增强**:包括`java.util.concurrent`包的引入,提供了线程安全的...
JDK1.4,全称Java Development Kit Version 1.4,是Java编程语言历史上的一个重要版本,由Sun Microsystems(现已被Oracle公司收购)于2002年2月13日正式发布。这个版本在Java平台上引入了许多关键性的改进和新特性...
Java Development Kit(JDK)是Java编程语言的核心组件,它为开发者提供了编译、调试和运行Java应用程序所需的所有工具。JDK 1.4是Java历史上的一个重要版本,发布于2004年,它是Java 2平台标准版(J2SE)的一部分。...
JDK 1.4引入了NIO(非阻塞I/O),这是一个重要的改进,使得Java应用程序能够更有效地处理I/O操作。NIO允许程序选择多路复用器模型,而非传统的阻塞I/O,这极大地提高了服务器端应用的性能,尤其是处理大量并发连接...
Java开发工具JDK 1.4免安装版是一款专为编程人员设计的Java开发环境,无需繁琐的安装过程,可以直接解压使用。JDK(Java Development Kit)是Oracle公司提供的用于开发Java应用程序的重要软件包,它包含了Java编译器...
2. **NIO(New I/O)**: 新的I/O API,也称为非阻塞I/O,位于`java.nio`包中,为高性能、低延迟的I/O操作提供了新的选择,特别适合网络编程和大文件处理。 3. **异常链(Exception Chaining)**: 异常链允许一个...
JDK1.4在这个版本引入了正则表达式、NIO(New I/O)和异常链等新特性,这些都是Java开发者必须掌握的重要概念。 最后,`org`包通常用于开源组织或者标准组织的类库。在JDK1.4中,`org`可能包含了XML解析器、JUnit...
JDK 1.4是Java编程语言的一个重要版本,由Sun Microsystems在2003年发布。它包含了Java运行环境(Java Runtime Environment, JRE)以及开发工具,如Java编译器(javac)、Java应用程序启动器(java)和Java文档生成...
2. **NIO (New I/O)**:Java 1.4引入了非阻塞I/O模型,允许程序在处理大量并发连接时性能得到显著提升。NIO提供了Channel、Selector和Buffer等新类,为高性能网络编程提供了基础。 3. **正则表达式**:Java 1.4通过...
3. **NIO(Non-blocking I/O)**: 新的java.nio包提供了非阻塞I/O操作,极大地提高了网络编程和文件I/O的效率,尤其是在处理大量并发连接时。 4. **JDBC 2.0增强**: JDBC(Java Database Connectivity)API得到了...
JDK(Java Development Kit)是Java编程语言的核心工具集,包含了编译器、调试器、文档生成工具以及Java运行时环境。在1.4版本中,Java进行了许多重要的更新和改进,为开发者提供了更强大、更稳定、更高效的功能。 ...
3. **NIO(New I/O)**:非阻塞I/O(Non-blocking I/O)是JDK 1.4的一大亮点,通过java.nio包提供了异步I/O操作,极大地提高了高并发应用的性能。Channel、Buffer和Selector等组件使得处理大量连接变得更加高效。 4...
Java JDK 1.4是Java开发工具包的一个重要版本,它为开发者提供了丰富的编程接口(API),涵盖了Java语言的核心库、标准扩展库以及一些重要的新特性。本手册是针对这个版本的中文翻译,旨在帮助中国开发者更好地理解...
JDK 1.4还引入了一系列新的APIs和特性,如`java.nio.channels.spi.AbstractInterruptibleChannel`,`java.nio.channels.spi.AbstractSelectableChannel`,`java.nio.charset.StandardCharsets`等,这些APIs丰富了...
标题与描述均提到了“java-jdk1.4新特性介绍”,这暗示了文章的核心将围绕Java JDK 1.4版本中的新增功能进行探讨。Java作为一款广泛使用的编程语言,其每一次更新都伴随着一系列的新特性和性能提升,而JDK 1.4也不...
在软件开发领域,尤其是Java编程中,JDK(Java Development Kit)扮演着至关重要的角色。JDK是Oracle公司提供的用于开发和运行Java应用程序的工具集合,它包含了Java编译器、Java虚拟机(JVM)、Java类库以及各种...
"java"目录是核心Java库的所在,包括基本类型、集合框架、I/O流、多线程、网络编程等核心API。例如,"java.lang"包是最基础的包,包含所有Java程序都会用到的基本类,如Object、String、System等;"java.util"包提供...
3. **NIO (New I/O)**:非阻塞I/O模型,允许在多线程环境中更有效地处理I/O操作,提高了网络和文件系统的性能。 4. **集合框架的改进**:包括泛型的预览(正式引入在Java 5中),以及ConcurrentHashMap等并发容器的...