- 浏览: 527541 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
c7887qin:
貌似还要使用相同的证书进行签名。。。
Android - 如何将两个/多个应用放到一个进程中去? -
北极光之吻:
天天向上1989 写道不是有OnDoubleTapListen ...
android实现双击事件监听 -
nielong123:
nielong123 写道onCheckedChanged(M ...
Android RadioGroup 换行, 支持多行多列 -
nielong123:
onCheckedChanged(MultiRadioGrou ...
Android RadioGroup 换行, 支持多行多列 -
zk_Ming:
zk_Ming 写道我用了你的,但是radiogroup 点击 ...
Android RadioGroup 换行, 支持多行多列
本篇文章观点和例子来自 《Java网络编程精解》, 作者为孙卫琴, 出版社为电子工业出版社。
对于用ServerSocket 及 Socket 编写的服务器程序和客户程序, 他们在运行过程中常常会阻塞. 例如, 当一个线程执行 ServerSocket 的accept() 方法时, 假如没有客户连接, 该线程就会一直等到有客户连接才从 accept() 方法返回. 再例如, 当线程执行 Socket 的 read() 方法时, 如果输入流中没有数据, 该线程就会一直等到读入足够的数据才从 read() 方法返回.
假如服务器程序需要同时与多个客户通信, 就必须分配多个工作线程, 让他们分别负责与一个客户通信, 当然每个工作线程都有可能经常处于长时间的阻塞状态.
从 JDK1.4 版本开始, 引入了非阻塞的通信机制. 服务器程序接收客户连接, 客户程序建立与服务器的连接, 以及服务器程序和客户程序收发数据的操作都可以按非阻塞的方式进行. 服务器程序只需要创建一个线程, 就能完成同时与多个客户通信的任务.
非阻塞的通信机制主要由 java.nio 包(新I/O包) 中的类实现, 主要的类包括 ServerSocketChannel, SocketChannel, Selector, SelectionKey 和 ByteBuffer 等.
本章介绍如何用 java.nio 包中的类来创建服务器程序和客户程序, 并且 分别采用阻塞模式和非阻塞模式来实现它们. 通过比较不同的实现方式, 可以帮助读者理解它们的区别和适用范围.
一. 线程阻塞的概念
在生活中, 最常见的阻塞现象是公路上汽车的堵塞. 汽车在公路上快速行驶, 如果前方交通受阻, 就只好停下来等待, 等到交通畅顺, 才能恢复行驶.
线程在运行中也会因为某些原因而阻塞. 所有处于阻塞状态的线程的共同特征是: 放弃CPU, 暂停运行, 只有等到导致阻塞的原因消除, 才能恢复运行; 或者被其他线程中断, 该线程会退出阻塞状态, 并且抛出 InterruptedException.
1.1 线程阻塞的原因
导致线程阻塞的原因主要有以下几方面.
线程执行了 Thread.sleep(int n) 方法, 线程放弃 CPU, 睡眠 n 毫秒, 然后恢复运行.
线程要执行一段同步代码, 由于无法获得相关的同步锁, 只好进入阻塞状态, 等到获得了同步锁, 才能恢复运行.
线程执行了一个对象的 wait() 方法, 进入阻塞状态, 只有等到其他线程执行了该对象的 notify() 和 notifyAll() 方法, 才可能将其呼醒.
线程执行 I/O 操作或进行远程通信时, 会因为等待相关的资源而进入阻塞状态. 例如, 当线程执行 System.in.read() 方法时, 如果用户没有向控制台输入数据, 则该线程会一直等读到了用户的输入数据才从 read() 方法返回.
进行远程通信时, 在客户程序中, 线程在以下情况可能进入阻塞状态.
请求与服务器建立连接时, 即当线程执行 Socket 的带参数构造方法, 或执行 Socket 的 connect() 方法时, 会进入阻塞状态, 直到连接成功, 此线程才从 Socket 的构造方法或 connect() 方法返回.
线程从 Socket 的输入流读入数据时, 如果没有足够的数据, 就会进入阻塞状态, 直到读到了足够的数据, 或者到达输入流的末尾, 或者出现了异常, 才从输入流的 read() 方法返回或异常中断. 输入流中有多少数据才算足够呢? 这要看线程执行的 read() 方法的类型.
> int read(): 只要输入流中有一个字节, 就算足够.
> int read( byte[] buff): 只要输入流中的字节数目与参数buff 数组的长度相同, 就算足够.
> String readLine(): 只要输入流中有一行字符串, 就算足够. 值得注意的是, InputStream 类并没有 readLine() 方法, 在过滤流 BufferedReader 类中才有此方法.
线程向 Socket 的输出流写一批数据时, 可能会进入阻塞状态, 等到输出了所有的数据, 或者出现异常, 才从输出流 的 write() 方法返回或异常中断.
调用 SOcket 的setSoLinger() 方法设置了关闭 Socket 的延迟时间, 那么当线程执行 Socket 的 close() 方法时, 会进入阻塞状态, 直到底层 Socket 发送完所有剩余数据, 或者超过了 setSoLinger() 方法设置的延迟时间, 才从 close() 方法返回.
在服务器程序中, 线程在以下情况下可能会进入阻塞状态.
线程执行 ServerSocket 的 accept() 方法, 等待客户的连接, 直到接收到了客户连接, 才从 accept() 方法返回.
线程从 Socket 的输入流读入数据时, 如果输入流没有足够的数据, 就会进入阻塞状态.
线程向 Socket 的输出流写一批数据时, 可能会进入阻塞状态, 等到输出了所有的数据, 或者出现异常, 才从输出流的 write() 方法返回或异常中断.
由此可见, 无论在服务器程序还是客户程序中, 当通过 Socket 的输入流和输出流来读写数据时, 都可能进入阻塞状态. 这种可能出现阻塞的输入和输出操作被称为阻塞 I/O. 与此对照, 如果执行输入和输出操作时, 不会发生阻塞, 则称为非阻塞 I/O.
1.2 服务器程序用多线程处理阻塞通信的局限
本书第三章的第六节(创建多线程的服务器) 已经介绍了服务器程序用多线程来同时处理多个客户连接的方式. 服务器程序的处理流程如图 4-1 所示. 主线程负责接收客户的连接. 在线程池中有若干工作线程, 他们负责处理具体的客户连接. 每当主线程接收到一个客户连接, 就会把与这个客户交互的任务交给一个空闲的工作线程去完成, 主线程继续负责接收下一个客户连接.
图4-1 服务器程序用多线程处理阻塞通信
在图4-1 总, 用粗体框标识的步骤为可能引起阻塞的步骤. 从图中可以看出, 当主线程接收客户连接, 以及工作线程执行 I/O 操作时, 都有可能进入阻塞状态.
服务器程序用多线程来处理阻塞 I/O, 尽管能满足同时响应多个客户请求的需求, 但是有以下局限:
⑴ Java 虚拟机会为每个线程分配独立的堆栈空间, 工作线程数目越多, 系统开销就越大, 而且增加了 Java虚拟机调度线程的负担, 增加了线程之间同步的复杂性, 提高了线程死锁的可能性;
⑵ 工作线程的许多时间都浪费在阻塞 I/O 操作上, Java 虚拟机需要频繁地转让 CPU 的使用权, 使进入阻塞状态的线程放弃CPU, 再把CPU 分配给处于可运行状态的线程.
由此可见, 工作线程并不是越多越好. 如图 4-2 所示, 保持适量的工作线程, 会提高服务器的并发性能, 但是当工作线程的数目达到某个极限, 超出了系统的负荷时, 反而会减低并发性能, 使得多数客户无法快速得到服务器的响应.
图4-2 线程数目与并发性能的更新
1.3 非阻塞通信的基本思想
假如要同时做两件事: 烧开水和烧粥. 烧开水的步骤如下:
锅里放水, 打开煤气炉;
等待水烧开; //阻塞
关闭煤气炉, 把开水灌到水壶里;
烧粥的步骤如下:
锅里放水和米, 打开煤气炉;
等待粥烧开; //阻塞
调整煤气炉, 改为小火;
等待粥烧熟; //阻塞
关闭煤气炉;
为了同时完成两件事, 一个方案是同时请两个人分别做其中的一件事, 这相当于采用多线程来同时完成多个任务. 还有一种方案是让一个人同时完成两件事, 这个人应该善于利用一件事的空闲时间去做另一件事, 一刻也不应该闲着:
锅子里放水, 打开煤气炉; //开始烧水
锅子力放水和米, 打开煤气炉; //开始烧粥
while(一直等待, 直到有水烧开, 粥烧开或粥烧熟事件发生){ //阻塞
if(水烧开)
关闭煤气炉, 把开水灌到水壶里;
if(粥烧开)
调整煤气炉, 改为小火;
if(粥烧熟)
关闭煤气炉;
if(水已经烧开并且粥已经烧熟)
退出循环;
} //这里的煤气炉我可以理解为每件事就有一个煤气炉配给吧, 这也是一部分的开销呢
//并且if里面的动作必须要能快速完成的才行, 不然后面的就要排队了
//如是太累的工作还是不要用这个好
这个人不断监控烧水及烧粥的状态, 如果发生了 "水烧开", "粥烧开" 或 "粥烧熟" 事件, 就去处理这些事件, 处理完一件事后进行监控烧水及烧粥的状态, 直到所有的任务都完成.
以上工作方式也可以运用到服务器程序中, 服务器程序只需要一个线程就能同时负责接收客户的连接, 接收各个客户发送的数据, 以及向各个客户发送响应数据. 服务器程序的处理流程如下:
while(一直等待, 直到有接收连接就绪事件, 读就绪事件或写就绪事件发生){ //阻塞
if(有客户连接)
接收客户的连接; //非阻塞
if(某个 Socket 的输入流中有可读数据)
从输入流中读数据; //非阻塞
if(某个 Socket 的输出流可以写数据)
向输出流写数据; //非阻塞
}
以上处理流程采用了轮询的工作方式, 当某一种操作就绪时, 就执行该操作, 否则就查看是否还有其他就绪的操作可以执行. 线程不会因为某一个操作还没有就绪, 就进入阻塞状态, 一直傻傻地在那里等待这个操作就绪.
为了使轮询的工作方式顺利进行, 接收客户的连接, 从输入流读数据, 以及向输出流写数据的操作都应该以非阻塞的方式运行. 所谓非阻塞, 就是指当线程执行这些方法时, 如果操作还没有就绪, 就立即返回, 而不会一直等到操作就绪. 例如, 当线程接收客户连接时, 如果没有客户连接, 就立即返回; 再例如, 当线程从输入流中读数据时, 如果输入流中还没有数据, 就立即返回, 或者如果输入流还没有足够的数据, 那么就读取现有的数据, 然后返回. 值得注意的是, 以上 while 学校条件中的操作还是按照阻塞方式进行的, 如果未发生任何事件, 就会进入阻塞状态, 直到接收连接就绪事件, 读就绪事件或写就绪事件中至少有一个事件发生时, 才会执行 while 循环体中的操作. 在while 循环体中, 一般会包含在特定条件下退出循环的操作.
二. java.nio 包中的主要类
java.nio 包提供了支持非阻塞通信的类.
ServerSocketChannel: ServerSocket 的替代类, 支持阻塞通信与非阻塞通信.
SocketChannel: Socket 的替代类, 支持阻塞通信与非阻塞通信.
Selector: 为ServerSocketChannel 监控接收连接就绪事件, 为 SocketChannel 监控连接就绪, 读就绪和写就绪事件.
SelectionKey: 代表 ServerSocketChannel 及 SocketChannel 向 Selector 注册事件的句柄. 当一个 SelectionKey 对象位于Selector 对象的 selected-keys 集合中时, 就表示与这个 SelectionKey 对象相关的事件发生了.
ServerSocketChannel 及 SocketChannel 都是 SelectableChannel 的子类, 如图 4-3 所示. SelectableChannel 类及其子类都能委托 Selector 来监控他们可能发生的一些事件, 这种委托过程也称为注册事件过程.
对于用ServerSocket 及 Socket 编写的服务器程序和客户程序, 他们在运行过程中常常会阻塞. 例如, 当一个线程执行 ServerSocket 的accept() 方法时, 假如没有客户连接, 该线程就会一直等到有客户连接才从 accept() 方法返回. 再例如, 当线程执行 Socket 的 read() 方法时, 如果输入流中没有数据, 该线程就会一直等到读入足够的数据才从 read() 方法返回.
假如服务器程序需要同时与多个客户通信, 就必须分配多个工作线程, 让他们分别负责与一个客户通信, 当然每个工作线程都有可能经常处于长时间的阻塞状态.
从 JDK1.4 版本开始, 引入了非阻塞的通信机制. 服务器程序接收客户连接, 客户程序建立与服务器的连接, 以及服务器程序和客户程序收发数据的操作都可以按非阻塞的方式进行. 服务器程序只需要创建一个线程, 就能完成同时与多个客户通信的任务.
非阻塞的通信机制主要由 java.nio 包(新I/O包) 中的类实现, 主要的类包括 ServerSocketChannel, SocketChannel, Selector, SelectionKey 和 ByteBuffer 等.
本章介绍如何用 java.nio 包中的类来创建服务器程序和客户程序, 并且 分别采用阻塞模式和非阻塞模式来实现它们. 通过比较不同的实现方式, 可以帮助读者理解它们的区别和适用范围.
一. 线程阻塞的概念
在生活中, 最常见的阻塞现象是公路上汽车的堵塞. 汽车在公路上快速行驶, 如果前方交通受阻, 就只好停下来等待, 等到交通畅顺, 才能恢复行驶.
线程在运行中也会因为某些原因而阻塞. 所有处于阻塞状态的线程的共同特征是: 放弃CPU, 暂停运行, 只有等到导致阻塞的原因消除, 才能恢复运行; 或者被其他线程中断, 该线程会退出阻塞状态, 并且抛出 InterruptedException.
1.1 线程阻塞的原因
导致线程阻塞的原因主要有以下几方面.
线程执行了 Thread.sleep(int n) 方法, 线程放弃 CPU, 睡眠 n 毫秒, 然后恢复运行.
线程要执行一段同步代码, 由于无法获得相关的同步锁, 只好进入阻塞状态, 等到获得了同步锁, 才能恢复运行.
线程执行了一个对象的 wait() 方法, 进入阻塞状态, 只有等到其他线程执行了该对象的 notify() 和 notifyAll() 方法, 才可能将其呼醒.
线程执行 I/O 操作或进行远程通信时, 会因为等待相关的资源而进入阻塞状态. 例如, 当线程执行 System.in.read() 方法时, 如果用户没有向控制台输入数据, 则该线程会一直等读到了用户的输入数据才从 read() 方法返回.
进行远程通信时, 在客户程序中, 线程在以下情况可能进入阻塞状态.
请求与服务器建立连接时, 即当线程执行 Socket 的带参数构造方法, 或执行 Socket 的 connect() 方法时, 会进入阻塞状态, 直到连接成功, 此线程才从 Socket 的构造方法或 connect() 方法返回.
线程从 Socket 的输入流读入数据时, 如果没有足够的数据, 就会进入阻塞状态, 直到读到了足够的数据, 或者到达输入流的末尾, 或者出现了异常, 才从输入流的 read() 方法返回或异常中断. 输入流中有多少数据才算足够呢? 这要看线程执行的 read() 方法的类型.
> int read(): 只要输入流中有一个字节, 就算足够.
> int read( byte[] buff): 只要输入流中的字节数目与参数buff 数组的长度相同, 就算足够.
> String readLine(): 只要输入流中有一行字符串, 就算足够. 值得注意的是, InputStream 类并没有 readLine() 方法, 在过滤流 BufferedReader 类中才有此方法.
线程向 Socket 的输出流写一批数据时, 可能会进入阻塞状态, 等到输出了所有的数据, 或者出现异常, 才从输出流 的 write() 方法返回或异常中断.
调用 SOcket 的setSoLinger() 方法设置了关闭 Socket 的延迟时间, 那么当线程执行 Socket 的 close() 方法时, 会进入阻塞状态, 直到底层 Socket 发送完所有剩余数据, 或者超过了 setSoLinger() 方法设置的延迟时间, 才从 close() 方法返回.
在服务器程序中, 线程在以下情况下可能会进入阻塞状态.
线程执行 ServerSocket 的 accept() 方法, 等待客户的连接, 直到接收到了客户连接, 才从 accept() 方法返回.
线程从 Socket 的输入流读入数据时, 如果输入流没有足够的数据, 就会进入阻塞状态.
线程向 Socket 的输出流写一批数据时, 可能会进入阻塞状态, 等到输出了所有的数据, 或者出现异常, 才从输出流的 write() 方法返回或异常中断.
由此可见, 无论在服务器程序还是客户程序中, 当通过 Socket 的输入流和输出流来读写数据时, 都可能进入阻塞状态. 这种可能出现阻塞的输入和输出操作被称为阻塞 I/O. 与此对照, 如果执行输入和输出操作时, 不会发生阻塞, 则称为非阻塞 I/O.
1.2 服务器程序用多线程处理阻塞通信的局限
本书第三章的第六节(创建多线程的服务器) 已经介绍了服务器程序用多线程来同时处理多个客户连接的方式. 服务器程序的处理流程如图 4-1 所示. 主线程负责接收客户的连接. 在线程池中有若干工作线程, 他们负责处理具体的客户连接. 每当主线程接收到一个客户连接, 就会把与这个客户交互的任务交给一个空闲的工作线程去完成, 主线程继续负责接收下一个客户连接.
图4-1 服务器程序用多线程处理阻塞通信
在图4-1 总, 用粗体框标识的步骤为可能引起阻塞的步骤. 从图中可以看出, 当主线程接收客户连接, 以及工作线程执行 I/O 操作时, 都有可能进入阻塞状态.
服务器程序用多线程来处理阻塞 I/O, 尽管能满足同时响应多个客户请求的需求, 但是有以下局限:
⑴ Java 虚拟机会为每个线程分配独立的堆栈空间, 工作线程数目越多, 系统开销就越大, 而且增加了 Java虚拟机调度线程的负担, 增加了线程之间同步的复杂性, 提高了线程死锁的可能性;
⑵ 工作线程的许多时间都浪费在阻塞 I/O 操作上, Java 虚拟机需要频繁地转让 CPU 的使用权, 使进入阻塞状态的线程放弃CPU, 再把CPU 分配给处于可运行状态的线程.
由此可见, 工作线程并不是越多越好. 如图 4-2 所示, 保持适量的工作线程, 会提高服务器的并发性能, 但是当工作线程的数目达到某个极限, 超出了系统的负荷时, 反而会减低并发性能, 使得多数客户无法快速得到服务器的响应.
图4-2 线程数目与并发性能的更新
1.3 非阻塞通信的基本思想
假如要同时做两件事: 烧开水和烧粥. 烧开水的步骤如下:
锅里放水, 打开煤气炉;
等待水烧开; //阻塞
关闭煤气炉, 把开水灌到水壶里;
烧粥的步骤如下:
锅里放水和米, 打开煤气炉;
等待粥烧开; //阻塞
调整煤气炉, 改为小火;
等待粥烧熟; //阻塞
关闭煤气炉;
为了同时完成两件事, 一个方案是同时请两个人分别做其中的一件事, 这相当于采用多线程来同时完成多个任务. 还有一种方案是让一个人同时完成两件事, 这个人应该善于利用一件事的空闲时间去做另一件事, 一刻也不应该闲着:
锅子里放水, 打开煤气炉; //开始烧水
锅子力放水和米, 打开煤气炉; //开始烧粥
while(一直等待, 直到有水烧开, 粥烧开或粥烧熟事件发生){ //阻塞
if(水烧开)
关闭煤气炉, 把开水灌到水壶里;
if(粥烧开)
调整煤气炉, 改为小火;
if(粥烧熟)
关闭煤气炉;
if(水已经烧开并且粥已经烧熟)
退出循环;
} //这里的煤气炉我可以理解为每件事就有一个煤气炉配给吧, 这也是一部分的开销呢
//并且if里面的动作必须要能快速完成的才行, 不然后面的就要排队了
//如是太累的工作还是不要用这个好
这个人不断监控烧水及烧粥的状态, 如果发生了 "水烧开", "粥烧开" 或 "粥烧熟" 事件, 就去处理这些事件, 处理完一件事后进行监控烧水及烧粥的状态, 直到所有的任务都完成.
以上工作方式也可以运用到服务器程序中, 服务器程序只需要一个线程就能同时负责接收客户的连接, 接收各个客户发送的数据, 以及向各个客户发送响应数据. 服务器程序的处理流程如下:
while(一直等待, 直到有接收连接就绪事件, 读就绪事件或写就绪事件发生){ //阻塞
if(有客户连接)
接收客户的连接; //非阻塞
if(某个 Socket 的输入流中有可读数据)
从输入流中读数据; //非阻塞
if(某个 Socket 的输出流可以写数据)
向输出流写数据; //非阻塞
}
以上处理流程采用了轮询的工作方式, 当某一种操作就绪时, 就执行该操作, 否则就查看是否还有其他就绪的操作可以执行. 线程不会因为某一个操作还没有就绪, 就进入阻塞状态, 一直傻傻地在那里等待这个操作就绪.
为了使轮询的工作方式顺利进行, 接收客户的连接, 从输入流读数据, 以及向输出流写数据的操作都应该以非阻塞的方式运行. 所谓非阻塞, 就是指当线程执行这些方法时, 如果操作还没有就绪, 就立即返回, 而不会一直等到操作就绪. 例如, 当线程接收客户连接时, 如果没有客户连接, 就立即返回; 再例如, 当线程从输入流中读数据时, 如果输入流中还没有数据, 就立即返回, 或者如果输入流还没有足够的数据, 那么就读取现有的数据, 然后返回. 值得注意的是, 以上 while 学校条件中的操作还是按照阻塞方式进行的, 如果未发生任何事件, 就会进入阻塞状态, 直到接收连接就绪事件, 读就绪事件或写就绪事件中至少有一个事件发生时, 才会执行 while 循环体中的操作. 在while 循环体中, 一般会包含在特定条件下退出循环的操作.
二. java.nio 包中的主要类
java.nio 包提供了支持非阻塞通信的类.
ServerSocketChannel: ServerSocket 的替代类, 支持阻塞通信与非阻塞通信.
SocketChannel: Socket 的替代类, 支持阻塞通信与非阻塞通信.
Selector: 为ServerSocketChannel 监控接收连接就绪事件, 为 SocketChannel 监控连接就绪, 读就绪和写就绪事件.
SelectionKey: 代表 ServerSocketChannel 及 SocketChannel 向 Selector 注册事件的句柄. 当一个 SelectionKey 对象位于Selector 对象的 selected-keys 集合中时, 就表示与这个 SelectionKey 对象相关的事件发生了.
ServerSocketChannel 及 SocketChannel 都是 SelectableChannel 的子类, 如图 4-3 所示. SelectableChannel 类及其子类都能委托 Selector 来监控他们可能发生的一些事件, 这种委托过程也称为注册事件过程.
发表评论
-
Android 修改Android签名证书keystore的密码、别名alias以及别名的密码
2015-04-27 10:35 1236转载请注明出处:http://blog.csdn.net/ ... -
基本HTTP请求回顾
2014-12-24 11:40 925HttpURLConnection为javaAPI提供的一种R ... -
Android签名验证简介
2014-05-16 10:15 5384Android原生自带了个安装器(packages\apps ... -
正则表达式大全
2014-03-18 17:05 1008正则表达式匹配网址: (https://[\w]*.|http ... -
正则表达式大全
2014-03-18 16:53 0正则表达式匹配网址: (https://[\w]*.|http ... -
jni jstring 、char* 类型的转换
2014-03-06 18:20 837jni jstring 、char* 类型的转换 //jst ... -
基于 Android NDK 的学习之旅-----资源释放
2014-01-11 14:37 1134转载于http://www.cnblogs.com ... -
Android系统手机端抓包方法
2013-06-25 11:42 1013抓包准备 1. Android手机需要先获得root权限。 ... -
Android捕获异常
2013-04-03 14:52 1064如果有些异常是运行时异常,你无法捕获,但是又不想让程序 ... -
JAVA比较器报错:Comparison method violates its general contract
2013-02-05 13:03 13854java.lang.IllegalArgumentExcept ... -
java.lang.IllegalStateException: tried to write 1544 bytes with content-length
2013-01-31 14:57 1416上传文件时,content-length定义的长度小于 ... -
Javadoc生成方法
2013-01-23 14:30 1063方法1:在eclipse中生成 ... -
eclipse 开导入android 第三方jar包java heap space问题解决
2013-01-22 17:25 2521最近做android应用需要使用第三方的jar包,结果导入到e ... -
Java MD5加密
2012-12-03 15:01 907import java.security.*; imp ... -
解决android网络异常java.net.SocketException: Bad address family
2012-10-22 11:28 3244在Android系统中进行网络开发时,如果使用了java.ni ... -
怎么让JButton的大小适应图片的大小
2012-10-09 18:36 4426可以自己来设置大小: ImageIcon icon = new ... -
Android开发进阶之NIO非阻塞包(八)
2012-09-25 15:59 0在整个DDMS中体现Android NIO主要框架的要数Mon ... -
Android开发进阶之NIO非阻塞包(七)
2012-09-25 15:58 0今天我们继续就Android DDMS源码一起分析NIO非阻塞 ... -
Android开发进阶之NIO非阻塞包(六)
2012-09-25 15:58 0有关Android NIO的相关内容,本次Android123 ... -
Android开发进阶之NIO非阻塞包(五)
2012-09-25 15:56 1060有关Android NIO的注意点和重点今天Android12 ...
相关推荐
通过java网络编程深入理解socket阻塞通信和非阻塞通信的在网络中的应用 源码包每一行都有注释,在代码里面每一个类都有详细的注释来解释这个类的功能这个方法的功能,调用哪一个类的哪一个功能等等。 压缩包包含实验...
以上内容总结了使用Python实现socket非阻塞通讯功能的原理和技巧,包括单进程基本写法、多线程实现、服务端和客户端的具体编程方法等。对于想要深入学习Python网络编程的朋友,文中推荐了多个专题教程,如《Python ...
● SocketChannel:Socket的替代类,支持阻塞通信与非阻塞通信。 ● Selector:为ServerSocketChannel监控接收连接就绪事件,为SocketChannel监控连接就绪、读就绪和写就绪事件。 ● SelectionKey:代表...
本话题主要探讨的是在C++ Socket编程中的阻塞模式与非阻塞模式,以及它们在多线程环境下的应用和资源管理。 一、阻塞与非阻塞模式 1. **阻塞模式**:在阻塞模式下,当一个Socket调用(如recv或send)执行时,如果...
在通过一天学习,慢慢摸索中,研究出来了自己成果!
为了提高效率,可以采用多线程或者非阻塞I/O(如NIO,Java的新I/O库)来改进。但是,对于初学者来说,理解单线程阻塞模型是学习网络编程的基础,有助于深入理解Socket通信的工作原理。 此外,源码分析可以帮助我们...
### Socket C++ TCP阻塞与非阻塞服务器客户端开发 #### 概述 本文档将详细介绍如何使用C++ Winsock库来开发TCP非阻塞服务器。通过本篇内容的学习,您将了解到设置socket函数为非阻塞模式的方法,并且能够深入了解...
Java Socket 开发即时通讯服务器是构建实时通信系统的关键技术之一,尤其在企业级应用、在线游戏、聊天室等场景中广泛应用。本篇将深入探讨Java Socket在即时通讯服务器开发中的核心概念、步骤以及关键技术。 首先...
本文将深入探讨如何使用MFC实现非阻塞Socket通信,并结合protobuf(Protocol Buffers)作为数据交换格式,构建一个允许多个客户端与单一服务器进行通信的系统。 首先,我们来理解“非阻塞Socket”。在传统的阻塞...
在标题"socket非阻塞超时设置"中,我们关注的是如何配置Socket使其在等待数据时不会永久阻塞,并且能够设定一个超时时间。这种方式适用于那些需要快速响应或者避免程序因长时间等待而挂起的场景。 非阻塞模式是...
java socket USB和 串口通讯,使用java程序与硬件通讯的三种方式。
Linux 客户端Socket 非阻塞 connect 编程详解 本文档详细介绍了 Linux 客户端 Socket 非阻塞 connect 编程的实现方法和原理。非阻塞 connect 是一种高效的网络编程技术,能够提高程序的性能和可靠性。 一、非阻塞 ...
在这个"socket多线程例程非阻塞模式"的示例中,我们将深入探讨如何在Windows平台上实现多线程的socket通信,并了解非阻塞模式的工作原理。 首先,让我们来理解Socket的基本概念。Socket是进程间通信(IPC)的一种...
Linux下的Socket编程实例(阻塞和非阻塞) 通过分析给定的文件信息,我们可以生成以下知识点: Socket编程概述 Socket 编程是指使用操作系统提供的 socket 编程接口来实现网络通信的编程方式。Socket 编程可以实现...
本篇文章将深入探讨“DELPHI SOCKET 阻塞通讯”这一主题。 首先,我们需要了解什么是Socket。Socket是网络通信中的一个端点,它允许两个或多个应用程序通过网络交换数据。在Delphi中,我们可以使用 Indy 或 Winsock...
本篇主要关注的是Socket编程中的阻塞和非阻塞模式,这两种模式在处理I/O操作时有着显著的区别。 阻塞Socket(Blocking Socket)是最基础的Socket编程模型。当一个Socket被设置为阻塞模式时,调用recv()或send()等...
标题中的"java_sx.rar_java socket _java 通讯_socket"暗示了这个压缩包可能包含了一些关于使用Java Socket进行网络通信的示例代码或教程资料。Java Socket通信通常涉及以下关键知识点: 1. **Socket类与...
- **NIO(非阻塞I/O)**:Java NIO库提供了非阻塞的Socket编程模型,适用于高并发场景,如`Selector`和`Channel`。 7. **实践应用** - **聊天应用**:基于Socket的简单聊天室,客户端发送消息到服务器,服务器...
### Linux UDP Socket 非阻塞模式与阻塞模式的区别详解 #### 一、引言 在进行网络编程时,我们经常会遇到阻塞模式与非阻塞模式的选择问题。这两种模式直接影响程序的运行效率和资源利用率。本文将详细介绍在Linux...