Java异步通信
服务器端:
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
public class TCPServer {
protected Selector selector;
protected Charset charset = Charset.forName("UTF-8");
protected CharsetEncoder charsetEncoder = charset.newEncoder();
protected CharsetDecoder charsetDecoder = charset.newDecoder();
int count = 1;
/**
* @throws Exception
*/
public TCPServer() throws Exception{
this(8888);
}
/**
* @param port
* @throws Exception
*/
public TCPServer(int port) throws Exception {
selector = Selector.open();
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(port)); // port
ssc.configureBlocking(false);
ssc.register(selector, SelectionKey.OP_ACCEPT);// register
while (true) {
// selector 线程。select() 会阻塞,直到有客户端连接,或者有消息读入
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove(); // 删除此消息
// 并在当前线程内处理
handleSelectionKey(selectionKey);
}
}
}
/**
* @param selectionKey
* @throws Exception
*/
public void handleSelectionKey(SelectionKey selectionKey) throws Exception {
if (selectionKey.isAcceptable()) {
ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();
SocketChannel socketChannel = ssc.accept();
socketChannel.configureBlocking(false);
Socket socket = socketChannel.socket();
// 立即注册一个 OP_READ 的SelectionKey, 接收客户端的消息
SelectionKey key = socketChannel.register(selector,SelectionKey.OP_READ);
SocketAddress clientInfo = socket.getRemoteSocketAddress();
key.attach("第 " + (count++) + " 个客户端 [" + clientInfo + "]");
// 打印
println(key.attachment() + " 连接成功");
} else if (selectionKey.isReadable()) {
// 有消息进来
ByteBuffer byteBuffer = ByteBuffer.allocate(100);
SocketChannel sc = (SocketChannel) selectionKey.channel();
try {
int len = sc.read(byteBuffer);
// 如果len>0,表示有输入。如果len==0, 表示输入结束。需要关闭 socketChannel
if (len > 0) {
byteBuffer.flip();
String msg = charsetDecoder.decode(byteBuffer).toString();
println(selectionKey.attachment() + " :" + msg);
// 根据客户端的消息,查找到对应的输出
String newMsg = "****************";
ByteBuffer bt = charsetEncoder.encode(CharBuffer.wrap(newMsg + "\n"));
sc.write(bt);
} else {
// 输入结束,关闭 socketChannel
println(selectionKey.attachment()+ " 已关闭连接");
sc.close();
}
} catch (Exception e) {
// 如果read抛出异常,表示连接异常中断,需要关闭 socketChannel
e.printStackTrace();
sc.close();
}
} else if (selectionKey.isWritable()) {
println("TODO: isWritable()");
} else if (selectionKey.isConnectable()) {
println("TODO: isConnectable()");
} else {
println("TODO: else");
}
}
/**
* @param object
*/
public static void println(Object object) {
System.out.println(object);
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
new TCPServer();
}
}
客户端:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.io.InputStream;
public class TCPClient extends Thread {
public void run() {
try {
Socket socket = new Socket("127.0.0.1", 8888);
OutputStream ous = socket.getOutputStream();
InputStream ins = socket.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(ins, "UTF-8"));
// 发送服务器
ous.write(">>>>>>>>>>>>>>>>".getBytes("UTF-8"));
ous.flush();
// 接收给服务器
System.out.println(">>>> " + r.readLine());
// 发送服务器
ous.write("<<<<<<<<<<<<<<<<".getBytes("UTF-8"));
ous.flush();
// 接收服务器
System.out.println(">>>> " + r.readLine());
Thread.sleep(3*1000);
ins.close();
ous.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
for (int i = 0; i < 3; i++) {
try {
new TCPClient().start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Java异步通信的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- JAVA NIO 类库的异步通信框架netty和mina
Netty 和 Mina 我究竟该选择哪个? 根据我的经验,无论选择哪个,都是个正确的选择.两者各有千秋,Netty 在内存管理方面更胜一筹,综合性能也更优.但是,API 变更的管理和兼容性做的不是太 ...
- JAVA NIO异步通信框架MINA选型和使用的几个细节(概述入门,UDP, 心跳)
Apache MINA 2 是一个开发高性能和高可伸缩性网络应用程序的网络应用框架.它提供了一个抽象的事件驱动的异步 API,可以使用 TCP/IP.UDP/IP.串口和虚拟机内部的管道等传输方式.A ...
- c#与JAVA利用SOCKET实现异步通信的SanNiuSignal.DLL已开源
大家好,前段时间C#的SanNiuSignal.DLL已开源;因部分用户特需要JAVA版的SanNiuSignal;现在只能把半成品先拿出来暂时给他们用了,以后再慢慢改进; JAVA版目前已实现跟C# ...
- Java基础知识强化之网络编程笔记24:Android网络通信之 AndroidAsync(基于nio的异步通信库)
1. AndroidAsync AndroidAsync 是一个基于nio的异步socket ,http(客户端服务器端),websocket,socket.io库,AndroidAsync 是一 ...
- Java消息队列--JMS概述
1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...
- 【历史】JavaScript和Java没啥关系!————JavaScript简史
文章的开始先上张图: 图片拍摄自北京图书大厦,代表着现在国内应该是绝大部分书店的现状--Javascript书籍放在Java类当中.甚至很多业内人也一直认为Javascript是Java语言在浏览器内 ...
- 3.开发Java消息驱动bean实例代码
java消息服务(JMS)是用于访问企业消息系统的开发商中立的API.企业消息系统可以协助应用软件通过网络进行消息交互.应用程序A发送一条消息到消息服务器的某个目的地(Destination),然后消 ...
- JMS(Java消息服务)入门教程
什么是Java消息服务 Java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建.发送.读取消息等,用于支持JAVA应用程序开发.在J2EE中 ...
随机推荐
- [APIO2010]
A.特别行动队 n<=1000000 看了数据范围和题目感觉就像是斜率优化,然后瞎推了一波式子,没想到A了. sij表示i+1到j的权值和. j比k优秀 $$fj+a*sij^{2}+b*si ...
- JVM学习记录-对象已死吗
前言 先来回顾一下,在jvm运行时数据区,分为两部分,一个部分是线程共享区,主要包括堆和方法区,另一部是线程私有区分包括本地方法栈,虚拟机栈和程序计数器.在线程私有部分的三个区域是随着线程生和灭的.栈 ...
- Django中数据查询(万能下换线,聚合,F,Q)
数据查询中万能的下划线基本用法: __contains: 包含 __icontains: 包含(忽略大小写) __startswith: 以什么开头 __istartswith: 以什么开头(忽略大小 ...
- I/O控制的主要功能
主要功能: 1. 解释用户的I/O系统调用.将用户I/O系统调用转换为I/O控制模块认识的命令模式. 2. 设备驱动.根据得到的I/O命令,启动物理设备完成指定的I/O操作. 3. 中断处理.对 ...
- c++中双冒号的作用
双冒号(::)用法 参考链接:https://segmentfault.com/a/1190000000345680 1.表示“域操作符”例:声明了一个类A,类A里声明了一个成员函数void f(), ...
- 计科1702冯亚杰C语言程序设计预备作业
阅读邹欣老师的博客--师生关系,针对文中的几种师生关系谈谈你的看法,你期望的师生关系是什么样的? 答:首先老师和学生之间要互相尊重,我认为这是必要的.在第一点的基础上师生要互相帮助,互相配合,共同进步 ...
- div英文内容超过div长度
添加css word-break: normal;word-wrap: break-word;
- idea和androidstudio的首次git配置一些问题
网上都有很清楚的步骤 但是 都是教怎么使用 但是对第一次应用idea内部vcs的git 则很少有详细说明 首先要在网上创建个项目 然后本地git clone下来 不建议内部vcs的fetch from ...
- 深入理解Java类加载器(1):Java类加载原理解析
1 基本信息 每个开发人员对Java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...
- python:浅析python 中__name__ = '__main__' 的作用(转载)
每次看文章的源码时,Python的主程序中都会看到开头有这个,查了一下作用:https://www.cnblogs.com/alan-babyblog/p/5147770.html. 讲的很详细,就直 ...