java 异步socket_java Socket读写异步分离

在Android开发中,基于Socket的通信必须是非阻塞式的,因此需要Reader和Writer异步分离,此外需要监听Socket网络状态、

监听接口

package com.io.sockets;

import java.io.IOException;

import java.net.Socket;

public interface SocketStatusListener

{

public static final int STATUS_OPEN = 0x01<<0;

public static final int STATUS_CLOSE = 0x01<<1;

public static final int STATUS_RESET = 0x01<<2;

public static final int STATUS_PIP_BROKEN = 0x01<<3;

public static final int STATUS_UNKOWN = 0x01<<4;

public void onSocketStatusChanged(Socket socket,int status,IOException e);

}

Handler读写处理控制

package com.io.sockets;

import java.io.IOException;

import java.net.Socket;

public  class SocketHandler implements SocketStatusListener {

private Socket socket=null;

private ReaderTask reader;

private WriterTask writer;

public SocketHandler(Socket socket) throws IOException {

this.socket = socket;

this.socket.setTcpNoDelay(true);

reader = new ReaderTask(socket);

writer = new WriterTask(socket);

onSocketStatusChanged(socket, STATUS_OPEN, null);

}

/**

* sendMessage:(这里用一句话描述这个方法的作用). 

* TODO(这里描述这个方法适用条件 – 可选).

*/

public  void sendMessage(String msg) {

writer.send(msg);

}

public void listen(boolean isListen)

{

reader.startListener(this);

}

public void shutDown() {

if(!socket.isClosed() &&socket.isConnected())

{

try {

writer.finish();

reader.finish();

socket.close();

} catch (IOException e) {

e.printStackTrace();

onSocketStatusChanged(socket, STATUS_CLOSE, e);

}finally{

reader = null;

writer = null;

System.out.println("Socket连接已关闭!!");

}

}

}

@Override

public void onSocketStatusChanged(Socket socket,int status, IOException e) {

switch (status) {

case SocketStatusListener.STATUS_CLOSE:

case SocketStatusListener.STATUS_RESET:

case SocketStatusListener.STATUS_PIP_BROKEN:

shutDown();

break;

default:

break;

}

}

}

读取任务

package com.io.sockets;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.Socket;

import java.net.SocketException;

public  class ReaderTask extends Thread{

private SocketStatusListener socketStatusListener;

private BufferedReader bufferedReader;

private Socket socket;

private boolean listening;

public ReaderTask(Socket socket) throws IOException

{

bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

this.socket = socket;

}

/**

* finish:(这里用一句话描述这个方法的作用). 

* TODO(这里描述这个方法适用条件 – 可选).

* @throws IOException

*

*/

public void finish() throws IOException

{

listening = false;

interrupt();

if(bufferedReader!=null && socket!=null)

{

if(socket.isInputShutdown())

{

socket.shutdownInput();

}

bufferedReader.close();

}

}

/* (non-Javadoc)

* @see java.lang.Runnable#run()

*/

@Override

public synchronized  void run()

{

while (listening)

{

String readStr = null;

try {

while((readStr=bufferedReader.readLine())!=null)

{

System.err.println("[Server]:"+readStr);

}

} catch (IOException e) {

listening = false;

if(socketStatusListener!=null)

{

int status = parseSocketStatus(e);

socketStatusListener.onSocketStatusChanged(socket, status, e);

}

e.printStackTrace();

return;//终止线程继续运行,这里也可以使用continue

}

}

}

private int parseSocketStatus(IOException e)

{

if(SocketException.class.isInstance(e))

{

String msg = e.getLocalizedMessage().trim();

if("Connection reset".equalsIgnoreCase(msg))

{

return SocketStatusListener.STATUS_RESET;

}

else if("Socket is closed".equalsIgnoreCase(msg))

{

return SocketStatusListener.STATUS_CLOSE;

}

else if("Broken pipe".equalsIgnoreCase(msg))

{

return SocketStatusListener.STATUS_PIP_BROKEN;

}

}

return SocketStatusListener.STATUS_UNKOWN;

}

/**

* listen:(这里用一句话描述这个方法的作用). 

* TODO(这里描述这个方法适用条件 – 可选).

*

*/

public void startListener(SocketStatusListener ssl) {

listening = true;

this.socketStatusListener = ssl;

start();

}

}

写入任务

package com.io.sockets;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.OutputStreamWriter;

import java.net.Socket;

public  class WriterTask extends Thread{

private BufferedWriter bufferedWriter;

private String msg = null;

private Socket socket = null;

public WriterTask(Socket socket) throws IOException {

this.bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

this.socket = socket;

}

/**

* finishTask:(这里用一句话描述这个方法的作用). 

* TODO(这里描述这个方法适用条件 – 可选).

* @throws IOException

*

*/

public void finish() throws IOException {

if(bufferedWriter!=null && socket!=null)

{

if(!socket.isOutputShutdown())

{

socket.shutdownOutput();

}

bufferedWriter.close();

}

}

/* (non-Javadoc)

* @see java.lang.Runnable#run()

*/

@Override

public synchronized void run() {

try {

bufferedWriter.write(msg);

bufferedWriter.flush();

} catch (IOException e) {

e.printStackTrace();

}

}

public void send(String msg){

this.msg = msg;

new Thread(this).start();

}

}

Server端测试

public class TcpSocketServer {

public static void main(String[] args) {

List serverHandlers = new CopyOnWriteArrayList();

ServerSocket serverSocket = null;

try {

serverSocket = new ServerSocket(8090, 5);

while(true)

{

Socket clientSocket = serverSocket.accept();

if(clientSocket.isConnected())

{

SocketHandler serverHandler = new SocketHandler(clientSocket);

serverHandlers.add(serverHandler);

serverHandler.listen(true);

serverHandler.sendMessage("Host:"+serverSocket.getInetAddress().getHostAddress()+"\r\n");

/*while (true)

{

Scanner sc = new Scanner(System.in);

String next = sc.nextLine()+"\r\n";

for (SocketHandler scItem : serverHandlers) {

scItem.sendMessage(next);

}

}*/

}

}

} catch (IOException e) {

e.printStackTrace();

}finally{

try {

for (SocketHandler serverHandler : serverHandlers)

{

serverHandler.shutDown();

}

serverHandlers.clear();

serverSocket.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

客户端测试

public class TcpSocketClient {

public static void main(String[] args) {

SocketHandler clientHandler = null;

try {

Socket clientSocket = new Socket("localhost", 8090);

clientSocket.setKeepAlive(true);

clientSocket.setTcpNoDelay(true);

if(clientSocket.isConnected())

{

clientHandler = new SocketHandler(clientSocket);

clientHandler.listen(true);

while (true)

{

Scanner sc = new Scanner(System.in);

String next = sc.nextLine()+"\r\n";

if(!clientSocket.isClosed())

{

clientHandler.sendMessage(next);

}else{

break;

}

}

}

} catch (IOException e) {

e.printStackTrace();

}finally{

clientHandler.shutDown();

}

}

}

原文:http://my.oschina.net/ososchina/blog/509052

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427194.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows下安装mysql服务

1.下载 首先上MySql的官网下载 https://dev.mysql.com/downloads/mysql/ &#xff0c;本人下载的是 mysql-5.7.24-winx64.zip版。 2.解压存放目录 下载完解压到你想要存放的位置 我的是解压到D:\Program Files\MySQL 。 3.配置环境变量 在环境变量path中追加一句&#xff1a;;D…

web.xml 配置文件 超详细说明!!!

一、web.xml是什么&#xff1f; 首先 web.xml 是java web 项目的一个重要的配置文件&#xff0c;但是web.xml文件并不是Java web工程必须的。 web.xml文件是用来配置&#xff1a;欢迎页、servlet、filter等的。当你的web工程没用到这些时&#xff0c;你可以不用web.xml文件来配…

python条件表达式三门课至少有一门及格_Python/ MySQL练习题(一)

Python/ MySQL练习题(一)2、查询“生物”课程比“物理”课程成绩高的所有学生的学号1 SELECT2 *3 FROM4 (5 SELECT6 *7 FROM8 course9 LEFT JOIN score ON score.course_id course.cid10 WHERE11 course.cname ‘生物‘12 ) AS A13 INNER JOIN (14 SELECT15 *16 FROM17 course…

window上安装mysql服务核心版(亲测可用)

上次安装服务启动后&#xff0c;这次又准备重新安装&#xff0c;出现了了很多问题 1首先我们还是去官网下载对应的window安装包 2放置在D:\Program Files\mysql下面&#xff0c;没有则新建一个Program Files 3在同路径下E:\Program Files\mysql建立一个my.ini文件 [mysql] 设置…

java添加信息_java – 向异常添加信息

我想向堆栈跟踪/异常添加信息.基本上我现在有这样的东西,我真的很喜欢&#xff1a;Exception in thread "main" java.lang.ArithmeticException: / by zeroat com.so.main(SO.java:41)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect…

python封装模块_Python练手,封装日志模块,v2

前面第1版写好后&#xff0c;很凌乱&#xff0c;主要的问题在于&#xff0c;Python不支持方法重载&#xff0c;想要灵活创建对象&#xff0c;当时的变通办法是&#xff0c;先链式地有选择地设置属性(方法重载的本质就是有选择地设置属性)&#xff0c;再做实例化&#xff0c;这样…

发现了拯救“文献多的一团麻”的工具

Endnotes是一款好的文献管理工具; 可用以收集文献&#xff1b;整理在引用文献时的不知所踪(提前在reference中细化标题)&#xff1b;还有一些在阅读文献时 转瞬即逝的灵感(notes); 使用笔记来自&#xff1a;感谢其悉心编写。 http://blog.sciencenet.cn/blog-484734-367968.htm…

windows安装apache

1打开apache官网http://httpd.apache.org/ 下载win版本 2解压放入D盘D:\Apache24 3修改http.conf,安装路径 端口改成8080&#xff0c;避免占用&#xff0c;原先是80 4http -t检查配置文件合法 5httpd -k install -n apache安装主服务 6net start apache

java语言中的标识符_Java语言基本语法(一)————关键字标识符(Java语言标识符命名规范Java语言的包名、类名、接口名、变量名、函数名、常量名命名规则 )...

一、关键字关键字的定义和特点定义&#xff1a;被Java语言赋予特殊含义&#xff0c;用做专门用途的字符串(单词)。特点&#xff1a;关键字中所有字母均为小写下面列举一些常用的关键字。用于定义数据类型的关键字&#xff1a;byte、short、int、long、float、double、char、boo…

数组的合并和升序排列_leetcode No.31 下一个排列

题目链接&#xff1a;下一个排列 - 力扣&#xff08;LeetCode&#xff09;​leetcode-cn.com题目描述&#xff1a;实现获取下一个排列的函数&#xff0c;算法需要将给定数字序列重新排列成字典序中下一个更大的排列。如果不存在下一个更大的排列&#xff0c;则将数字重新排列成…

公司网络故障那些事(路由器变交换机)

首先这次网络故障是断电引起的 我给大家画个模型 三层的为八口交换机 一层的为五口打印机 笔记本代表两台无线打印机 首先八口的连接了公司采购电脑一台&#xff0c;业务电脑一台&#xff0c;其他电脑三台 第二个五口交换的连接财务电脑两台 最后一个五口交换机连接两台无线打印…

【原创】大公司为什么还在采用过时的技术

背景 本文出自一朋友给我的提问&#xff0c;于是博主呕心沥血给他花式洗脑了几个小时。忽然发现&#xff0c;应该还有许多朋友有同样的疑问。所以整理成文。 许多刚毕业的程序员朋友&#xff0c;都有一个执念&#xff0c;想要进那种规模大一点的公司、上市的、业内有名的最好。…

java 文件上传 配置_SpringMVCMultipartFilefile文件上传及参数接收

一、form表单属性中加上enctype"multipart/form-data"form表单的二、配置文件中配置MultipartResolver文件超出限制会在进入controller前抛出异常&#xff0c;在允许范围内这个配置无影响三、MultipartFile接受文件并通过IO二进制流(MultipartFile.getInputStream())…

list foreach方法_Java集合三兄弟List,Set,Map你分的清楚吗?

前言集合作为Java基础知识的核心部分&#xff0c;不论是在面试还是平时工作中都是经常遇见的。当然面对熟悉的List、Set、Map&#xff0c;面试管的提问一般也都不会从简单的问题出发了&#xff0c;今天就来聊下集合中的高级部分&#xff0c;让你对它们的理解更加清楚。一、List…

centos7.3防火墙配置

Centos7.3防火墙配置 1、查看firewall服务状态 systemctl status firewalld 2、查看firewall的状态 firewall-cmd --state 3、开启、重启、关闭、firewalld.service服务 开启 service firewalld start 重启 service firewalld restart 关闭 service firewalld stop 4、…

SpringBoot使用Jsp

本文是简单总结一下SpringBoot使用Jsp的Demo。 前言 在早期做项目的时候&#xff0c;JSP是我们经常使用的java服务器页面&#xff0c;其实就是一个简化servlet的设计&#xff0c;在本文开始之前&#xff0c;回顾一下jsp的几大对象&#xff0c;如图。 而在现在SpringBoot框架流行…

java 持久_Java持久锁总结 -解道Jdon

并发主题Java与持久相关的锁总结本文总结Java中有关数据库保存持久数据的锁机制&#xff0c;不只是纯粹数据库自身的锁&#xff0c;本文主要就Java持久层三个技术数据库、JPA和Hibernate的锁应用进行了总结。在并发理论中&#xff0c;锁是用于保护可变的共享数据&#xff0c;以…

cacti 监控安装失败

1首先这是基于lnmp模式进行的 2yum安装 yum -y install httpd mysql mysql-server php php-mysql php-json php-pdo 3lib库 yum -y install cairo-devel libxml2-devel pango pango-devel 4 解压rrdtool-1.3.1.tar.gz Cd rrdtool-1.3.1 ./configure --prefix/usr/local/rrdtoo…

project 模板_施工进度横道图不会做?18份计划模板收藏好,输入参数迅速成图...

施工进度横道图不会做&#xff1f;18份计划模板收藏好&#xff0c;输入参数迅速成图作为施工组织设计的关键内容&#xff0c;施工进度计划控制了工程施工进度、工程施工期限等各项施工活动。进度计划是否合理&#xff0c;直接影响施工速度、成本和质量。因此施工中的其他工作必…

JavaScript学习系列3 -- JavaScript arguments对象学习

在实际项目开发中&#xff0c;目前还是很少使用到JavaScript 中的arguments对象&#xff0c;那么它到底是干什么用的呢 arguments是JavaScript中的一个类数组对象&#xff0c;它代表传给一个正在执行的函数function的参数列表。 看完这个定义&#xff0c;需要明白&#xff0c…