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

时间:2022-09-03 23:01:29

在做关于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 -- 案例:名字合并&lpar;监听data数据的改变&rpar;

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

  2. java Socket&lpar;TCP&rpar;编程小项目

    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. 广播接收者案例&lowbar;sd卡状态监听

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

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

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

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

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

随机推荐

  1. Spring bean依赖注入、bean的装配及相关注解

    依赖注入 Spring主要提供以下两种方法用于依赖注入 基于属性Setter方法注入 基于构造方法注入 Setter方法注入 例子: public class Communication { priv ...

  2. C&plus;&plus;基本数据类型总结

    一.整形 1.整形有char.short.int.long.long long,这5个也默认为signed XX ; 规则:short至少16位:int至少和short一样:long至少32位,且至少 ...

  3. LwIP移植和使用

    LwIP移植和使用 本手册基于lwip-1.4.x编写,本人没有移植过1.4.0之前的版本,更早的版本或许有差别.如果看官发现问题欢迎联系<QQ: 937431539  email: 93743 ...

  4. 使用JQuery Ajax请求,在Controller里获取Session

    昨天在做项目的时候,两个平台之间的切换,虽然两个网站的Session都指向了同一台机子,但是通过Ajax方式来请求时,就是不能获取到Session的值. 在调试的过程中发现,原来是Session的Is ...

  5. spring mvc实现查询

    实体类:User package cn.bdqn.pojo; public class User { private String userName; private String password; ...

  6. SVG绘制圆形简单示例分享

    今天分享“svg绘制圆形”部分 1.简单圆形 效果图如下: 关键代码: <svg xmlns="http://www.w3.org/2000/svg" version=&qu ...

  7. Android设置RadioButton在文字的右边

    效果图如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro ...

  8. &lpar;stripTrailingZeros&rpar;A &equals;&equals; B hdu2054

    A == B ? 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2054 Problem Description Give you two numbers ...

  9. Java基础教程&lpar;13&rpar;--包

      为了使类型更易于查找,避免命名冲突和访问控制,我们应该使用包来对自己定义的类型进行管理.这里说的类型可以是类.接口.枚举和注解(枚举和注解的内容会在后续教程中介绍).使用包来管理我们的代码,有以下 ...

  10. python --正则学习

    re的正则表达式语法    正则表达式语法表如下: re.match re.match 尝试从字符串的开始匹配一个模式,匹配成功返回match object,否则返回None. 如:下面的例子匹配第一 ...