使用Java NIO进行网络编程,看下服务端的例子

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; public class Server {
private static int PORT = 8000;
private static final long PAUSE_BETWEEEN_MSGS = 10; // millisecs
private static ByteBuffer echoBuffer = ByteBuffer.allocate(4);
private static ByteBuffer sendBuffer = ByteBuffer.allocate(256);
private static ConcurrentHashMap<Integer, SocketChannel> chm
= new ConcurrentHashMap<Integer, SocketChannel>();
private static int msg = 0; public static void main(String args[]) throws Exception {
Selector selector = Selector.open();
// Open a listener on each port, and register each one
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
InetSocketAddress address = new InetSocketAddress("localhost",PORT);
ssc.bind(address);
ssc.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Going to listen on " + PORT);
while (true){
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectedKeys.iterator(); System.out.println(selectedKeys.size());
while (it.hasNext()){
String msg = new String();
SelectionKey key = (SelectionKey) it.next();
if(key.isAcceptable()){
ServerSocketChannel sscNew = (ServerSocketChannel) key
.channel();
SocketChannel sc = sscNew.accept();
sc.configureBlocking(false);
// Add the new connection to the selector
sc.register(selector, SelectionKey.OP_READ);
// Add the socket channel to the list
chm.put(sc.hashCode(), sc);
it.remove();
}else if(key.isReadable()){
SocketChannel sc = (SocketChannel) key.channel();
int code = 0;
while ((code = sc.read(echoBuffer)) > 0) {
byte b[] = new byte[echoBuffer.position()];
echoBuffer.flip();
echoBuffer.get(b);
msg+=new String(b, "UTF-8");
}
// if(msg.length()>1)
// msg = msg.substring(0, msg.length()-2); //client关闭时,收到可读事件,code = -1
if (code == -1 ||
msg.toUpperCase().indexOf("BYE")>-1){
chm.remove(sc.hashCode());
sc.close();
} else {
//code=0,消息读完或者echoBuffer空间不够时,部分消息内容下一次select后收到
echoBuffer.clear();
}
System.out.println("msg: " + msg + " from: " + sc + "code: " + code );
it.remove(); //注册可写通知
sc.register(selector,SelectionKey.OP_WRITE);
}else if(key.isWritable()){
SocketChannel client = (SocketChannel) key.channel();
String sendTxt = "Message from Server";
sendBuffer.put(sendTxt.getBytes());
sendBuffer.flip();
int code = 0; //如果sendBuffer内容一次没有写完,会在下一次事件中处理吗?
while (client.write(sendBuffer) != 0){
}
if (code == -1 ){
chm.remove(client.hashCode());
client.close();
} else {
//code=0,消息写完
sendBuffer.clear();
}
it.remove();
System.out.println("Send message to client "); //在读通知里面注册为写事件,所以这里还需要注册为读,否则不在接受客户端消息
client.register(selector,SelectionKey.OP_READ);
}
}
Thread.sleep(5000);
}
}
}

使用windows telnet与服务端交互,在windows telnet中,需要使用send命令来按行发送消息,如下所示

一些说明:

1.select操作为阻塞操作,直至至少一个事件发生

2.server端只需注册accept事件

3.read、write为非阻塞操作,需要在代码中判断返回结果

4.read操作,如果接受的buffer大小不够,会在下一次select操作中接受

5.write操作呢?如果消息没有发完,怎么处理,下面这种循环么?

while (buffer.hasRemaining()){
socketChannel.write(buffer);
}

6.register会覆盖,所以在读写处理中交替注册

Java NIO网络编程demo的更多相关文章

  1. Netty | 第1章 Java NIO 网络编程《Netty In Action》

    目录 前言 1. Java 网络编程 1.1 Javs NIO 基本介绍 1.2 缓冲区 Buffer 1.2 通道 Channel 1.3 选择器 Selector 1.4 NIO 非阻塞网络编程原 ...

  2. Java NIO 网络编程基础

    Java NIO提供了一套网络api,可以用来处理连接数很多的情况.他的基本思想就是用一个线程来处理多个channel. 123456789101112131415161718192021222324 ...

  3. java基础-网络编程(Socket)技术选型入门之NIO技术

    java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...

  4. Java面向对象 网络编程 下

    Java面向对象 网络编程  下 知识概要:                   (1)Tcp 练习 (2)客户端向服务端上传一个图片. (3) 请求登陆 (4)url 需求:上传图片. 客户端:   ...

  5. 二十三、Java基础--------网络编程

    Java中另一个重要技术就是网络编程了,为了更好的学习web方向的知识,有必要对java之网络编程好好学习,本文将围绕网络编程技术进行分析. 常见的网络协议:UDP.TCP UDP 1. 将数据源和目 ...

  6. JAVA的网络编程

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  7. Java Socket 网络编程心跳设计概念

    Java Socket 网络编程心跳设计概念   1.一般是用来判断对方(设备,进程或其它网元)是否正常动行,一 般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉.用于 ...

  8. 20145325张梓靖 实验五 "JAVA的网络编程"

    20145325张梓靖 实验五 "JAVA的网络编程" 实验内容 使用 JVAV语言 进行网络编程 对明文进行加密 设计过程 我完成的是客户端,服务端同伴 20145308刘昊阳 ...

  9. 【转】JAVA之网络编程

    转自:火之光 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者 ...

随机推荐

  1. Angular 富文本编辑之路的探索

    作者:杨振兴Worktile 前端工程师,PingCode Wiki 产品技术负责人 PingCode Wiki 提供结构化知识库来记载信息和知识,便于团队沉淀经验.共享资源,欢迎大家注册试用 本文主 ...

  2. Boom 3D带你聆听《我们的乐队》音乐盛宴

    说到前段时间大热的音乐类综艺节目,<我们的乐队>肯定值得一提.<我们的乐队>是由谢霆锋.萧敬腾.王俊凯担任导师,以团队的形式组成各种风格的乐队,并通过同场比拼,最终选出获胜的乐 ...

  3. cocoslua3.17 android机器上播放音效不全

    开发过程中遇到一个问题,一个8秒的音效,在android机器上播放不完就结束了:网上说是由于android播放音效的内存限制的:原因知道了,那怎么解决呢? 通过各种搜索查找发现还是解决不了问题,然后自 ...

  4. 【模板】【P3402】可持久化并查集

    (题面来自洛谷) 题目描述 n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 ...

  5. 完全图的最短Hamilton路径——状压dp

    题意:给出一张含有n(n<20)个点的完全图,求从0号节点到第n-1号节点的最短Hamilton路径.Hamilton路径是指不重不漏地经过每一个点的路径. 算法进阶上的一道状压例题,复杂度为O ...

  6. BackgroundService 大佬教的好

    BackgroundService 源码分析 因为换了工作也有两个多月没有写博客啦,因为跟着红超哥(大佬)一直在学习和做项目(反正就是在潜心修炼,大佬每天也是在我十万个为什么中度过的.) 最近在做一个 ...

  7. 测试:DOCX

    先拿到的是需求文档和接口文档以及测试用例模块,[以及之前写好的测试用例]再根据分配的任务进行编写用例 [智能看懂业务需求]现有功能点,在编写用例 [项目介绍]: 辽阳农商惠生活项目是作为一个农户和银行 ...

  8. java顺序、选择、循环结构

    一.顺序结构 二.选择结构 1.if都执行 2.if else if else 条件满足才执行 3.选择结构switch 一个case后有多条语句要加花括号 多个case的值不能相同 case中要加b ...

  9. macos brew zookeeper,安装后zookeeper启动失败?

    一.Zookeeper安装流程 执行如下安装命令: brew install zookeeper 执行截图如下: 安装后查看 zookeeper 安装信息(默认拉取最新版本) brew info zo ...

  10. Django搭建示例项目实战与避坑细节

    Django 开发项目是很快的,有多快?看完本篇文章,你就知道了. 安装 Django 前提条件:已安装 Python. Django 使用 pip 命令直接就可以安装: pip install dj ...