使用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. SHEIN:Java开发面经

    SHEIN面经 我觉得除技术外,自信是一个非常关键的点. 一面 自我介绍: 谈谈实习经历: 讲讲你实习的收获: 如何设计规范的接口?(简历上有写,所以问到) 当你需要修改两个月前的代码时,如何去整理以 ...

  2. vue项目中echarts属性总结

    <div id="echarts" style="width: 600px;height: 400px;margin-top: 100px;margin-left: ...

  3. django清理migration终极解决办法

    1.django生成数据表结构的过程 在我们设计好models以后,我们可以通过以下命令生成将要同步给数据库的数据结构文件 python manage.py makemigrations 生成的文件在 ...

  4. C# Random类的正确应用

    Random类介绍 Random类一个用于产生伪随机数字的类.这里的伪随机表示有随机性但是可以基于算法模拟出随机规律. Random类的构造方式有两种. Random r= new Random(). ...

  5. 有什么好用的Mac数据恢复软件

    对于第一次上手苹果电脑的人来说,使用起来难免有点小难受,因为对苹果电脑操作系统不熟练,发生误删数据的事情也是屡见不鲜. 那么对于这种情况我们该怎么办呢?不用担心,今天小编就为大家推荐一款好用的苹果数据 ...

  6. 从这三方面优化你的电脑,保持Mac运行流畅

    使用着Mac系统的用户都知道,Mac OS的各方面性能都很好,特别是流畅性,有人说不用清理垃圾也能流畅地使用Mac,但这的确是夸张了.电脑使用的时间长了,它的性能总会越来越退步,这其中有着系统垃圾拖累 ...

  7. leetcode152. 乘积最大子序列

    给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数).示例 1:输入: [2,3,-2,4]输出: 6解释: 子数组 [2,3] 有最大乘积 6.示例 2:输入: ...

  8. C语言讲义——函数

    为实现特定目的而编写的一段可被调用的代码 简单地讲:函数就是一组语句,取了个名字 别名:子例程(routine)/方法(Method,一般面向对象的语言使用这个叫法) 函数的组成部分 以主函数为例: ...

  9. C构造类型 数组

    一.数组是什么 一组有个固定大小.相同数据类型的数据的集合. 数组可以分为:一维数组.二维数组.三维数组....(维数不止一维:多维数组) 表格 : 行和列(二维数组) 二.一维数组 1.一般形式 类 ...

  10. C语言中Linux环境下编译与链接

    编写一个简单的 hello.c 文件,以此为例. 1.编译并链接一个完全包含于一个源文件的C程序. gcc hello.c gcc -Wall hello.c gcc -o hello hello.c ...