在传统的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 网络编程的更多相关文章

  1. JAVA基础知识之网络编程——-网络基础(Java的http get和post请求,多线程下载)

    本文主要介绍java.net下为网络编程提供的一些基础包,InetAddress代表一个IP协议对象,可以用来获取IP地址,Host name之类的信息.URL和URLConnect可以用来访问web ...

  2. Java基础教程:网络编程

    Java基础教程:网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个s ...

  3. java基础学习总结——网络编程

    一.网络基础概念 首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程.

  4. Java 基础高级2 网络编程

    1.协议的概念:通信双方事先约定好的通信规则 2七层网络通信协议:应用成,表示层,会话层,传输层,网络层,数据链路层 3.TCP/IP协议:点对点通信,三层握手,安全有保证 4.UDP协议;广播协议, ...

  5. JAVA基础知识之网络编程——-网络通信模型(IO模型)

    <Unix网络编程:卷1>中介绍了5中I/O模型,JAVA作为运行在宿主机上的程序,底层也遵循这5中I/O模型规则.这5中I/O模型分别是: 阻塞式IO 非阻塞式IO I/O复用 信号驱动 ...

  6. 【java基础学习】网络编程

    网络编程 InetAddress tcp udp

  7. 【Java基础总结】网络编程

    网络编程 InetAddress tcp udp

  8. JAVA基础知识之网络编程——-基于NIO的非阻塞Socket通信

    阻塞IO与非阻塞IO 通常情况下的Socket都是阻塞式的, 程序的输入输出都会让当前线程进入阻塞状态, 因此服务器需要为每一个客户端都创建一个线程. 从JAVA1.4开始引入了NIO API, NI ...

  9. JAVA基础知识之网络编程——-基于UDP协议的通信例子

    UDP是一种不可靠的协议,它在通信两端各建立一个socket,这两个socket不会建立持久的通信连接,只会单方面向对方发送数据,不检查发送结果. java中基于UDP协议的通信使用DatagramS ...

随机推荐

  1. php版本升级导致openssl无法使用

    也就是call to undefined function openssl错误: 把extension前面的注释去掉,甚至把“libeay32.dll和ssleay32.dll文件复制并替换到apac ...

  2. Linux Shell 内建命令:冒号(:)

    https://blog.csdn.net/honghuzhilangzixin/article/details/7073312/ 在Linux系统中,冒号(:)常用来做路径的分隔符(PATH),数据 ...

  3. 使用git pull与本地文件冲突

    出错信息如下: error: Your local changes to 'c/environ.c' would be overwritten by merge. Aborting. Please, ...

  4. jquery Load方法的重要点

    一个非常重要而且很容易忽视的问题就是:你是否load进了你必须load的元素,是否有的没有load进来,打开firebug查看一下

  5. Extjs4 上传图片并进行图片格式以及大小验证

    在做项目是遇到上传图片,并在前端限制图片上传的大小,下面就直接贴出主要的上传图片的代码,以及图片大小的验证,但前端没有验证图片的宽高验证 一.先创建出上传图片的组件,使用filefield组件 var ...

  6. js 高效拼接字符串

    <script>//如果我们大量使用+=进行字符串拼接的话,将会使界面失去响应(卡死状态) //高效拼接字符串 var StringBuilder=function() { this.da ...

  7. UploadFtp

    #!/bin/bash FILENAME=$ DSTDIR=$ FTPSRV=ip FTPUSER="user" FTPPWD="password" SRCDI ...

  8. Module build failed: Error: Cannot find module 'url-loader' 的坑

    本文地址:http://www.cnblogs.com/jying/p/8280956.html 开发环境:react.webpack.es5 引用图片报错:Module build failed: ...

  9. 3DMAX 批量 场景 对象 导出 .X格式 脚本

    一.首先你需要下载一个 Total Commader文件管理软件.利用这个软件你可以收集文件夹下包含子文件夹下的max文件(或完整路径)打开TotalCMD后使用查找文件:(如图红框中的操作)1. 2 ...

  10. PowerDesigner 逆向工程

    原文地址:https://www.cnblogs.com/feilong3540717/archive/2011/11/18/2254040.html PowserDesigner 的打开路径:Fil ...