java 基础之--nio 网络编程
在传统的Java 网络编程中,对于客户端的每次连接,对于服务器来说,都要创建一个新的线程与客户端进行通讯,这种频繁的线程的创建,对于服务器来说,是一种巨大的损耗,在Java 1.4 引入Java nio 引入了 selector channel buffer 对此操作进行重新的定义:
服务端:
package com.java.baseknowledge.net; import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set; public class NioService {
//store userMap
public static Map<Integer,SocketChannel> userMap =new HashMap<>();
public static void main(String[] args) throws Exception { //selector object
Selector selector =Selector.open();
//serversocketchannel object is listening client accept
ServerSocketChannel serverSocket =ServerSocketChannel.open();
//Adjusts this channel's blocking mode.
serverSocket.configureBlocking(false); serverSocket.bind(new InetSocketAddress(9099));
//在selector中register channel
serverSocket.register(selector, SelectionKey.OP_ACCEPT); while(true) {
//block method event listening,this method is perform when event is touch;
selector.select();
//get selection-key set
Set<SelectionKey> selectedKeys = selector.selectedKeys(); selectedKeys.forEach((keys->{
//judge selectionkey mode
if(keys.isAcceptable()) {
try {
ServerSocketChannel channel = (ServerSocketChannel)keys.channel();
//obtain socketchannel
SocketChannel accept = channel.accept();
accept.configureBlocking(false);
//regist selector,listening read event
accept.register(selector, SelectionKey.OP_READ);
userMap.put(new Random().nextInt()*new Random().nextInt(), accept); }
catch(Exception e ) {
e.printStackTrace();
}
} else if(keys.isReadable()) {
//obtain socketchannel
try {
SocketChannel channel = (SocketChannel)keys.channel();
System.out.println(channel);
ByteBuffer by = ByteBuffer.allocate(2048);
channel.read(by); userMap.forEach((k,v)->{ by.rewind();
if(v!=channel) {
try {
v.write(by);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}); }
catch(Exception e) {} }
selectedKeys.clear(); })); } } }
客户端:
package com.java.baseknowledge.net; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* chat client
* @author Administrator
*
*/
public class JavaNioClient { public static void main(String[] args) throws Exception { //建立Selector
Selector selector =Selector.open();
SocketChannel socketChannel=SocketChannel.open();
//设置非阻塞
socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_CONNECT); socketChannel.connect(new InetSocketAddress("127.0.0.1", 9099)); while(true) {
selector.select(); Set<SelectionKey> setionkey =selector.selectedKeys(); for(SelectionKey kk :setionkey) {
if(kk.isConnectable()) {
//从selectionkey 获取socketChannel
SocketChannel socket=(SocketChannel)kk.channel();
//手动建立连接
if(socket.isConnectionPending()) {
socket.finishConnect();
//写数据
ByteBuffer byteB = ByteBuffer.allocate(1024);
byteB.put((System.currentTimeMillis()+"连接ok").getBytes());
byteB.flip();
socket.write(byteB);
//jdk1.5 线程池
ExecutorService exe =Executors.newSingleThreadExecutor(Executors.defaultThreadFactory()); exe.submit(new Thread() { @Override
public void run() {
while(true) {
String msg=null;
byteB.clear();
//标准键盘输入
BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
try {
msg =br.readLine();
ByteBuffer bytec = ByteBuffer.allocate(1024);
bytec.put(msg.getBytes());
bytec.flip();
socket.write(bytec);
} catch (IOException e) { e.printStackTrace();
}
}
}
});
} socket.register(selector, SelectionKey.OP_READ);
}
else if(kk.isReadable()) { //从selectionkey 获取socketChannel
SocketChannel socket=(SocketChannel)kk.channel();
ByteBuffer by =ByteBuffer.allocate(1024);
int a=socket.read(by);
//if(a>0) {
String receive =new String(by.array());
System.out.println(receive);
//}
} setionkey.clear();
} } } }
java 基础之--nio 网络编程的更多相关文章
- JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)
本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...
- Java基础教程:网络编程
Java基础教程:网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个s ...
- java基础学习总结——网络编程
一.网络基础概念 首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程.
- Java 基础高级2 网络编程
1.协议的概念:通信双方事先约定好的通信规则 2七层网络通信协议:应用成,表示层,会话层,传输层,网络层,数据链路层 3.TCP/IP协议:点对点通信,三层握手,安全有保证 4.UDP协议;广播协议, ...
- JAVA基础知识之网络编程——-网络通信模型(IO模型)
<Unix网络编程:卷1>中介绍了5中I/O模型,JAVA作为运行在宿主机上的程序,底层也遵循这5中I/O模型规则.这5中I/O模型分别是: 阻塞式IO 非阻塞式IO I/O复用 信号驱动 ...
- 【java基础学习】网络编程
网络编程 InetAddress tcp udp
- 【Java基础总结】网络编程
网络编程 InetAddress tcp udp
- JAVA基础知识之网络编程——-基于NIO的非阻塞Socket通信
阻塞IO与非阻塞IO 通常情况下的Socket都是阻塞式的, 程序的输入输出都会让当前线程进入阻塞状态, 因此服务器需要为每一个客户端都创建一个线程. 从JAVA1.4开始引入了NIO API, NI ...
- JAVA基础知识之网络编程——-基于UDP协议的通信例子
UDP是一种不可靠的协议,它在通信两端各建立一个socket,这两个socket不会建立持久的通信连接,只会单方面向对方发送数据,不检查发送结果. java中基于UDP协议的通信使用DatagramS ...
随机推荐
- java script删除数组的方法集合(转载)
一.清空数组 var ary = [1,2,3,4]; ary.splice(0,ary.length);//清空数组 console.log(ary); // 输出 [],空数组,即被清空了 二.删 ...
- 【376】COMP 9021 相关笔记(二)
Note_01 zip() itertools.zip_longest() %time Note_02 for 循环单行输出 list 技巧 迭代器 生成器 map() zip() from path ...
- 查看Linux物理CPU个数
查看内核版本 lsb_release -a 查看物理CPU个数.核数.逻辑CPU个数 (1)具有相同core id的CPU是同一个core的超线程. (2)具有相同physical id的CPU是同一 ...
- 将 DNSCrypt 部署到 Openwrt 路由器上+ DNSmasq 解析国内域名用本地 DNS[ZT+实践]
原文地址: 1.https://typcn.com/legacy/blog/posts/openwrt-dnscypt.html 2.http://www.openwrt.pro/post-376.h ...
- PL/SQL编码规范的一些建议
由于业务的复杂多变,我们编写完的程序,在后期肯定要被修改,而且修改的人很可能不是自己.这种情况我们都遇到过. 而且,看别人的代码可能会觉得很痛苦:为什么他要这样写相关逻辑?为什么变量名称要这样定义?换 ...
- 检查浏览器是否已经启用Java支持功能
<script type="text/javascript"> document.write("navigator对象的方法"+"< ...
- 22.struts2-拦截器.md
目录 1.执行的流程时序图 1.执行的流程时序图 回顾: Struts配置: * 通配符.动态方法调用 * 全局跳转配置.配置的默认值.常量配置 * Struts核心业务 * 请求数据的自动封装 (p ...
- java解决查找问题
1.给定一个字符串,找到里面的大写字母和小写字母以及其他字母的个数: 代码: package test; public class Stringclass { public static void m ...
- C++ MFC常用函数(转)
WinExec() ExitWindowsEx() GlobalMemoryStatus() GetSystemInfo() GetSystemDirectory() GetWindowsDirect ...
- IIS 7配置需要注意的地方,RTX SDK运行必须Enable 32-bit Applications为True
简单说一下IIS 7的配置里那些需要注意的 首先每个网站都必须运行在特定得程序池上,程序池的配置中,关键的几个如下图: 1. .Net Framework Version : 这个设置的是你项目用到的 ...