使用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. 原生sql查询返回结果集处理方法

    今天博主用原生写查询的时候发现,查询出来的居然不是我数据表里的数据,而是一个对象 object(mysqli_result)#2 (5) { ["current_field"]=& ...

  2. java开发两年,连这些多线程知识都还没掌握,你凭什么涨薪!

    并发与并行 并发:两个或者多个事件在同一时间段发生(交替执行) 并行:两个或者多个事件在同一时刻发生(cpu多核.同时执行) 线程与进程 进程:是一个内存中运行的应用程序,有自己独立的内存空间,一个应 ...

  3. 你了解ABBYY FineReader 14么?

    有没有一款是能够同时处理纸质文档和个类型PDF的一站式解决方案?答案是肯定的,ABBYY FineReader 14集合了强大的光学字符识别(OCR)以及 PDF 查看和编辑功能.不仅能够高效识别图片 ...

  4. 《图解TCP/IP》第四章

    <图解TCP/IP>第四章 4.1 IP 即网际协议 4.1.1 IP(IPv4.IPv6)相当于OSI参考模型中的第3层-网络层 4.1.2 数据链路层和网络层的关系: 数据链路层的主要 ...

  5. python批量爬取猫咪图片

    不多说直接上代码 首先需要安装需要的库,安装命令如下 pip install BeautifulSoup pip install requests pip install urllib pip ins ...

  6. 【mq读书笔记】mq producer启动流程

    创建MQClientInstance实例.这里有个实例缓存 clienrId为客户端IP+instance+(unitname)注意到之前把instance替换为进程id,是为了instance为默认 ...

  7. CentOS初级扫盲

    发行版介绍 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX(可移植操作系统接口Portable Operating System Interface ,缩写为 POSIX ...

  8. mySQL初学者一定要掌握的数据操纵

    本文献给与作者一样不断地在追求梦想的小伙伴! 文章目录 1.INSERT 语句为表中所有字段添加数据 (1)可以指定所有字段名添加数据 (2)可以不指定字段名添加数据 (3)可以指定部分字段添加数据 ...

  9. 第四十一章、PyQt显示部件:TextBrowser、CalendarWidget、LCDNumber、ProgressBar、Label、HorizontalLine和VerticalLine简介

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 在Designer中,显示部件有Labe ...

  10. 转2:Python字符编码详解

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...