在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来

贴下课堂笔记:

在Java中使用NIO进行网络TCP套接字编程主要以下几个类:

ServerSocketChannel: 服务端套接字通道,主要监听接收客户端请求

Selector:通道选择器,主要用于管理服务端通道和所有客户端通道(监听通道中发生的事件),也就说是一个多路通道复用器。

SelectorKey: 事件选择键

SocketChannel: 套接字通道(客户端)

这篇文章《NIO编程中的SelectionKey.interestOps方法中的逻辑运算》解决了我一些疑问,地址:https://blog.csdn.net/woaiqianzhige/article/details/78696188

NIO 套接字服务端开发步骤:

  1. 创建选择器
  2. 启动服务端通道
  3. 设置服务端通道为非阻塞模式
  4. 将服务端通道注册到选择器
  5. 轮训通道事件
  6. 处理通道事件
  7. 关闭通道(可选)

案例:服务端接收客户端发送的短信息,服务端回复已收到。

服务端代码:

 import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set; public class Server {
private Selector selector;
private ServerSocketChannel serverSocketChannel;
private ByteBuffer byteBuffer = ByteBuffer.allocate(8192); /**
* 构造方法 启动服务器
*
* @param port
* @throws IOException
*/
public Server() {
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(10086));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server start successful with port: 10086");
} catch (ClosedChannelException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} public static void main(String[] args) throws Exception {
new Server().start();
} private void start() {
while (true) {
try {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = keys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
keyIterator.remove();
if (!key.isValid()) {
continue;
}
if (key.isAcceptable()) {
accept(key);
}
if (key.isReadable()) {
receive(key);
}
if (key.isWritable()) {
reply(key);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
} private void reply(SelectionKey key) {
try {
SocketChannel socketChannel = (SocketChannel) key.channel();
byteBuffer.clear();
String message = "receive success";
byteBuffer.put(message.getBytes());
byteBuffer.flip();
socketChannel.write(byteBuffer);
System.out.println("reply:" + message);
byteBuffer.clear();
key.interestOps(SelectionKey.OP_READ);
} catch (IOException e) {
e.printStackTrace();
}
} private void receive(SelectionKey key) {
try {
SocketChannel socketChannel = (SocketChannel) key.channel();
byteBuffer.clear();
int flag = socketChannel.read(byteBuffer);
if (flag == -1) {
key.channel().close();
key.cancel();
return;
}
byteBuffer.flip();
byte[] buf = new byte[byteBuffer.remaining()];
byteBuffer.get(buf);
String message = new String(buf);
System.out.println("receive message:" + message);
byteBuffer.clear();
key.interestOps(SelectionKey.OP_WRITE);
} catch (IOException e) {
e.printStackTrace();
}
} private void accept(SelectionKey key) {
try {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
System.out.println(Thread.currentThread().getName() + ": create client channel.");
} catch (ClosedChannelException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

客户端代码:

 import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner; public class Client {
private Selector selector;
private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
private SocketChannel socketChannel; public Client() {
try {
selector = Selector.open();
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
socketChannel.connect(new InetSocketAddress("127.0.0.1", 10086));
System.out.println("Client start successful");
} catch (ClosedChannelException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
new Client().start();
} private void start() {
while (true) {
try {
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (!key.isValid()) {
continue;
}
if (key.isConnectable()) {
if (socketChannel.finishConnect()) {
key.interestOps(key.interestOps() & ~SelectionKey.OP_CONNECT);
System.out.println("Client connect server success");
}
}
if (key.isReadable()) {
receive(key);
}
if (key.isWritable()) {
reply(key);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
} private void reply(SelectionKey key) {
try {
@SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
byteBuffer.clear();
System.out.println("please input message:");
String message = scanner.next();
byteBuffer.put(message.getBytes());
byteBuffer.flip();
socketChannel.write(byteBuffer);
byteBuffer.clear();
System.out.println("send message:" + message);
key.interestOps(SelectionKey.OP_READ);
} catch (IOException e) {
e.printStackTrace();
}
} private void receive(SelectionKey key) {
try {
byteBuffer.clear();
socketChannel.read(byteBuffer);
byteBuffer.flip();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
String message = new String(bytes).trim();
System.out.println("receive message: " + message);
byteBuffer.clear();
key.interestOps(SelectionKey.OP_WRITE);
} catch (IOException e) {
e.printStackTrace();
}
}
}

真是粗心大意了。。。特发此博文给我自己涨涨记性

在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来的更多相关文章

  1. vue学习-day05 -- 案例:名字合并(监听data数据的改变)

    1.案例:名字合并(监听data数据的改变) 使用keyup事件监听data数据的改变 <!DOCTYPE html> <html> <head> <titl ...

  2. java Socket(TCP)编程小项目

    package 服务器端相关操作; import java.io.Serializable; /* * 创建存储需要传输信息的对象,方便客户端向服务器端传送数据 */ public class Cli ...

  3. 微信小程序实现watch属性监听数据变化

    Vue 提供了一种通用的方式来观察和响应 Vue 实例上的数据变动:监听属性 watch. 虽然watch的滥用会导致性能不佳,但在一些情况下我们还是需要watch,使得代码更加简洁.逻辑更加清晰(其 ...

  4. Scratch编程小案例:愤怒的小牛

    愤怒的小鸟曾经很热门,网上还说他是程序员最喜欢玩的游戏.最先我是WIKIOI的评测页面看到他的,后来在2014年全国信息学奥林匹克联赛第一天第三题飞扬的小鸟也看到了它.因此,突然想做一个类似愤怒的小鸟 ...

  5. 《java入门第一季》之UDP协议下的网络编程小案例

    需求,一台电脑发送数据,其他电脑都可以收到该数据.使用广播地址. 发送端: import java.io.BufferedReader; import java.io.IOException; imp ...

  6. 小程序组件中有bindinput监听报异常

    真机上有问题,ide上是没问题的,   组件有处理函数,结果异常说页面没有处理函数,加上处理函数后就不报异常了.

  7. 广播接收者案例_sd卡状态监听

    (1)定义广播接收者 import android.content.BroadcastReceiver; import android.content.Context; import android. ...

  8. 《java入门第一季》之类小案例(模拟用户登录)

    首先是做一个用户登录的小案例.在此基础上加入其它逻辑. import java.util.Scanner; /* * 模拟登录,给三次机会,并提示还有几次.如果登录成功,就可以玩猜数字小游戏了. * ...

  9. 第13章 TCP编程(3)_基于自定义协议的多进程模型

    5. 自定义协议编程 (1)自定义协议:MSG //自定义的协议(TLV:Type length Value) typedef struct{ //协议头部 ];//TLV中的T unsigned i ...

随机推荐

  1. Scrapy爬虫框架补充内容一(Linux环境)

    Scrapy爬虫框架结构及工作原理详解 scrapy框架的框架结构如下: 组件分析: ENGINE:(核心):处理整个框架的数据流,各个组件在其控制下协同工作 SCHEDULER(调度器):负责接收引 ...

  2. Python_正则表达式一

    ''' 常用的正则表达式元字符 . 匹配换行符以外的任意单个字符 * 匹配位于'*'之前的字符或子模的0次或多次出现 + 匹配位于'+'之前的字符或子模式的1次或多次出现 - 用在[]之内用来表示范围 ...

  3. pycharm的安装及用法

    俗话说的好:"工欲善其事,必先利其器",程序员写代码,肯定不能在编译器里面写,这有一个全宇宙最好的python编译器,叫做pycharm ,他的优点呢,大家可以看一下: 优点:1, ...

  4. 安装ubuntu系统及ubuntu安装Python的几点心得

    一.安装ubuntu系统 1.ubuntu系统是Linux系统的一种,和centos差别不大,但是个人还是建议大家安装ubuntu,它更适合国内使用习惯,换句话说更亲切. 2.安装方法不再赘述,网上有 ...

  5. NIO之FileChannel类的理解和使用

    文章链接:http://blog.csdn.net/qq_16628781/article/details/70532307 知识点: FileChannel类及方法理解: 普通输入输出流复制文件: ...

  6. MySQL复制入门

    Ⅰ.复制类型 1.1 逻辑复制 记录每次逻辑操作 主从数据库可以不一致 1.2 物理逻辑复制 记录每次对于数据页的操作 主从数据物理严格一致 基于重做日志 说明: 如果一个块(页)修改了,就把这个修改 ...

  7. ucloud mysql

    [root@--- bin]# yum install mysql-server Loaded plugins: fastestmirror Setting up Install Process Lo ...

  8. java编程思想-第六章-某些练习题

    参考https://blog.csdn.net/caroline_wendy/article/details/47271037 3 package debug; import java.util.Ar ...

  9. netData.go 阅读源码

    ) // 定义数据传输结构 type NetData struct {     // 消息体     Body interface{}     // 操作代号     Operation string ...

  10. public_handers.go

    package],,) ],,) ]:],,);:],],,) ) ]],,) )) ,) ))         if etagMatch {             w.WriteHeader(ht ...