由于应用程序级别并没有使用多线程技术,这就导致了应用程序只能一个一个地对Socket 套接字进行处理。这个 Socket 套接宇没有处理完,就没法处理下一个 Socket 套接字 。针对这个 问题还是可以进行改进的:让应用程序层面上各个 Socket 套接字的处理相互不影响 。

服务端代码

package testBlockSocket;import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;//通过加入线程的概念,让 Socket Server 能够在应用层面
//通过非阻塞的方式同时处理多个 Socket 套接字
public class SocketServer4AllTimeoutAndMultiThread {private final static Logger LOGGER = LoggerFactory.getLogger(SocketServer4AllTimeoutAndMultiThread.class);private static Object xWait = new Object();public static void main(String[] args) throws Exception {ServerSocket serverSocket = new ServerSocket(8888);serverSocket.setSoTimeout(100);try {while (true) {Socket socket = null;try {socket = serverSocket.accept();} catch (SocketTimeoutException el) {// ===================// 执行到这里,说明本次 accept()方法没有接收到任何 TCP 连接主线程在这里就可以做一些事情,记为 x// ==================synchronized (SocketServer4AllTimeoutAndMultiThread.xWait) {LOGGER.info("这次没有接收到 TCP 连接,等待10 毫秒,模拟事件x 的处理时间 ");SocketServer4AllTimeoutAndMultiThread.xWait.wait(10);}continue;}// 业务处理过程可以交给一个线程(这里可以使用线程池)// 注意 , 线程的创建过程是很耗资源和时间的// 最终改变不了 accept ( )方法只能一个一个地接收 Socket 连接的情况SocketServerThreadWithTimeOut socketServerThread = new SocketServerThreadWithTimeOut(socket);new Thread(socketServerThread).start();}} catch (Exception e) {LOGGER.error(e.getMessage(), e);} finally {if (serverSocket != null) {serverSocket.close();}}}
}// 当然,接收到客户端的 Socket 后,业务的处理过程可以交给一个线程来做
class SocketServerThreadWithTimeOut implements Runnable {private final static Logger LOGGER = LoggerFactory.getLogger(SocketServerThreadWithTimeOut.class);private Socket socket;public SocketServerThreadWithTimeOut(Socket socket) {this.socket = socket;}@Overridepublic void run() {InputStream inputStream = null;OutputStream outputStream = null;try {inputStream = socket.getInputStream();outputStream = socket.getOutputStream();Integer sourcePort = socket.getPort();int maxLen = 2048;byte[] contextBytes = new byte[maxLen];int realLen;StringBuffer message = new StringBuffer();// 下面我们收取信息this.socket.setSoTimeout(10);BIORead: while (true) {try {while ((realLen = inputStream.read(contextBytes, 0, maxLen)) != -1) {message.append(new String(contextBytes, 0, realLen));// 我们同样假设读取到"over"关键字,表示业务内容传输完成if (message.indexOf("over") != -1) {break BIORead;}}} catch (SocketTimeoutException e2) {// =================// 执行到这里,说明本次 read ()方法没有接收到任何数据流主线程在这里又可以做一些事情,记为 Y// =================LOGGER.info("这次没有接收到任务数据报文,等待 10 ~盖秒 ,模拟事件 Y 的处理时间 ");continue;}}// 下面打印信息Long threadId = Thread.currentThread().getId();SocketServerThreadWithTimeOut.LOGGER.info("服务器(线程 :" + threadId + ")收到来自于端口 :" + sourcePort + "的信息: " + message);// 下面开始发送信息outputStream.write("回发响应信息:".getBytes());// 关闭 in 和 out 对象
            inputStream.close();outputStream.close();} catch (Exception e) {LOGGER.error(e.getMessage(), e);}}
}

引入了多线程技术后, I/O的处理吞吐量有了提高(实际上并不显著) ,因为 acceptO方法为“同步”工作的情况依然存在 。

转载于:https://www.cnblogs.com/gispathfinder/p/9029901.html

网络I/O模型--04非阻塞模式(解除accept()、 read()方法阻塞)的基础上加入多线程技术...相关推荐

  1. php mysql 非扫描,PHP的中使用非缓冲模式查询数据库的方法

    最近在开发一个PHP程序时遇到了下面的错误: PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted 错误信息显示允许的 ...

  2. java socket 阻塞模式_Java中Socket Read阻塞问题

    本人来说并不熟悉JAVA语言,只是近期在分析某个简单的java agent程序时,根据对应的代码写了一个对接的程序,两者之间是典型的C/S socket编程.客户端在向服务端发送相应的指令后,服务端( ...

  3. 如何利用装饰者模式在不改变原有对象的基础上扩展功能

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:双子孤狼 blog.csdn.net/zwx9001 ...

  4. [转]Socket的阻塞模式和非阻塞模式

    http://blog.csdn.net/VCSockets/ 阻塞模式 Windows套接字在阻塞和非阻塞两种模式下执行I/O操作.在阻塞模式下,在I/O操作完成前,执行的操作函数一直等候而不会立即 ...

  5. c# 非阻塞算法_C#阻塞模式和非阻塞模式

    阻塞模式 Windows套接字在阻塞和非阻塞两种模式下执行I/O操作.在阻塞模式下,在I/O操作完成前,执行的操作函数一直等候而不会立即返回,该函数所在的线程会阻塞在这里.相反,在非阻塞模式下,套接字 ...

  6. delphi Winsock非阻塞模式详解

    Winsockt的TClientSocket设置ClientType的属性为ctNonBlocking.则通讯模式为非阻塞模式. ctBlocking为阻塞模式,这里说一下阻塞与非阻塞的一些区别. c ...

  7. connect函数在阻塞和非阻塞模式下的行为

    connect函数在阻塞和非阻塞模式下的行为 当socket使用阻塞模式时,connect函数会阻塞到有明确结果才会返回,如果网络环境较差,可能要等一会,影响体验, 为了解决这个问题,我们使用异步co ...

  8. socket的阻塞模式和非阻塞模式

    文章目录 socket的阻塞模式和非阻塞模式 如何将socket设置为非阻塞模式 send和recv函数在阻塞和非阻塞模式下的表现 非阻塞模式下send和recv函数的返回值总结 阻塞与非阻塞sock ...

  9. js正则贪婪模式_JS关于正则的非贪婪模式

    首先正则是很复杂,很巧妙的. 你举的这个例子说明贪婪模式和非贪婪模式是不对的. 啥是贪婪模式,和非贪婪模式? 贪婪模式,就是"贪得无厌",有了还要,有多少要多少,指导没有(字符串尾 ...

最新文章

  1. 【转/TCP协议编程】 基于TCP的Socket 编程
  2. Caffe —— Deep learning in Practice 深度学习实践
  3. Jlink无法识别CPU/lpc2103/lpc2131
  4. 美团回应“大数据杀熟”;Docker开发者预览版支持M1芯片;GTK 4.0发布|极客头条...
  5. 《PaaS程序设计》一1.2 云能为创新做什么
  6. rust大油田分解机_辽河油田曙光采油厂:智慧党建建强战斗堡垒
  7. 开源html5游戏-少年行
  8. PL/SQL通过 scan ip 连接数据库
  9. 软件测试面试常见问题
  10. it高手与it民工区别
  11. office2016安装后右键新建没有word、excel、ppt等--解决方法总结
  12. MySQL之——mysql5.5 uuid做主键与int做主键的性能实测
  13. 为什么近几年一直在说互联网进入了下半场?
  14. 【C语言基础】C语言操作符
  15. DAC8568 Controller
  16. linux之下载工具那些事
  17. CTF Crypto 个人初级训练笔记
  18. 瑞芯微RK3568开发板核心板和底板
  19. 史上最全redis面试题及答案吊打面试官
  20. 微信直播是私域流量还是公域流量

热门文章

  1. 行政管理对计算机的要求,信息技术对行政管理的影响.doc
  2. CUDA C编程权威指南 第七章 调整指令级原语
  3. Python getattr
  4. Hadoop sqoop
  5. 4.5 面部验证与二分类
  6. Requests API
  7. 从IT应用架构角度,畅谈双活数据中心容灾解决方案
  8. 信贷系统学习总结(3)——现金贷之产品架构和信审系统
  9. Java基础学习总结(27)——7 款开源 Java 反编译工具
  10. kali linux 模板文件夹,详解kali linux 常用文件与指令路径