NIO服务端和客户端通信demo
代码转自 https://www.jianshu.com/p/a9d030fec081
服务端:
package nio; 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.*;
import java.util.concurrent.ConcurrentHashMap; public class Server {
private Selector selector;
private ByteBuffer readBuffer = ByteBuffer.allocate();//调整缓存的大小可以看到打印输出的变化
private ByteBuffer sendBuffer = ByteBuffer.allocate();//调整缓存的大小可以看到打印输出的变化 String str;
public void start() throws IOException {
// 打开服务器套接字通道
ServerSocketChannel ssc = ServerSocketChannel.open();
// 服务器配置为非阻塞
ssc.configureBlocking(false);
// 进行服务的绑定
ssc.bind(new InetSocketAddress("localhost", )); // 通过open()方法找到Selector
selector = Selector.open();
// 注册到selector,等待连接
ssc.register(selector, SelectionKey.OP_ACCEPT); while (!Thread.currentThread().isInterrupted()) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = keys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (!key.isValid()) {
continue;
}
if (key.isAcceptable()) {
accept(key);
} else if (key.isReadable()) {
read(key);
} else if (key.isWritable()) {
write(key);
}
keyIterator.remove(); //该事件已经处理,可以丢弃
}
}
} private void write(SelectionKey key) throws IOException, ClosedChannelException {
SocketChannel channel = (SocketChannel) key.channel();
System.out.println("write:"+str); sendBuffer.clear();
sendBuffer.put(str.getBytes());
sendBuffer.flip();
channel.write(sendBuffer);
channel.register(selector, SelectionKey.OP_READ);
} private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel(); // Clear out our read buffer so it's ready for new data
this.readBuffer.clear();
// readBuffer.flip();
// Attempt to read off the channel
int numRead;
try {
numRead = socketChannel.read(this.readBuffer);
} catch (IOException e) {
// The remote forcibly closed the connection, cancel
// the selection key and close the channel.
key.cancel();
socketChannel.close(); return;
} str = new String(readBuffer.array(), , numRead);
System.out.println(str);
socketChannel.register(selector, SelectionKey.OP_WRITE);
} private void accept(SelectionKey key) throws IOException {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = ssc.accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
System.out.println("a new client connected "+clientChannel.getRemoteAddress());
} public static void main(String[] args) throws IOException {
System.out.println("server started...");
new Server().start();
}
} 作者:御风逍遥
链接:https://www.jianshu.com/p/a9d030fec081
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
客户端:
package nio; import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set; public class Client { ByteBuffer writeBuffer = ByteBuffer.allocate();
ByteBuffer readBuffer = ByteBuffer.allocate(); public void start() throws IOException {
// 打开socket通道
SocketChannel sc = SocketChannel.open();
//设置为非阻塞
sc.configureBlocking(false);
//连接服务器地址和端口
sc.connect(new InetSocketAddress("localhost", ));
//打开选择器
Selector selector = Selector.open();
//注册连接服务器socket的动作
sc.register(selector, SelectionKey.OP_CONNECT); Scanner scanner = new Scanner(System.in);
while (true) {
//选择一组键,其相应的通道已为 I/O 操作准备就绪。
//此方法执行处于阻塞模式的选择操作。
selector.select();
//返回此选择器的已选择键集。
Set<SelectionKey> keys = selector.selectedKeys();
System.out.println("keys=" + keys.size());
Iterator<SelectionKey> keyIterator = keys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
keyIterator.remove();
// 判断此通道上是否正在进行连接操作。
if (key.isConnectable()) {
sc.finishConnect();
sc.register(selector, SelectionKey.OP_WRITE);
System.out.println("server connected...");
break;
} else if (key.isWritable()) { //写数据
System.out.print("please input message:");
String message = scanner.nextLine();
//ByteBuffer writeBuffer = ByteBuffer.wrap(message.getBytes());
writeBuffer.clear();
writeBuffer.put(message.getBytes());
//将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位
writeBuffer.flip();
sc.write(writeBuffer); //注册写操作,每个chanel只能注册一个操作,最后注册的一个生效
//如果你对不止一种事件感兴趣,那么可以用“位或”操作符将常量连接起来
//int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
//使用interest集合
sc.register(selector, SelectionKey.OP_READ);
sc.register(selector, SelectionKey.OP_WRITE);
sc.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()){//读取数据
System.out.print("receive message:");
SocketChannel client = (SocketChannel) key.channel();
//将缓冲区清空以备下次读取
readBuffer.clear();
int num = client.read(readBuffer);
System.out.println(new String(readBuffer.array(),, num));
//注册读操作,下一次读取
sc.register(selector, SelectionKey.OP_WRITE);
}
}
}
} public static void main(String[] args) throws IOException {
new Client().start();
}
} 作者:御风逍遥
链接:https://www.jianshu.com/p/a9d030fec081
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
NIO服务端和客户端通信demo的更多相关文章
- Netty 学习(二):服务端与客户端通信
Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...
- C#Winform窗体实现服务端和客户端通信例子(TCP/IP)
Winform窗体实现服务端和客户端通信的例子,是参考这个地址 http://www.cnblogs.com/longwu/archive/2011/08/25/2153636.html 进行了一些异 ...
- (C#:Socket)简单的服务端与客户端通信。
要求:1.可以完成一对一的通信:2.实现服务端对客户端一对多的选择发送:3.可以实现服务端的群发功能:4.可以实现客户端文件的发送: 要点:服务器端:第一步:用指定的端口号和服务器的ip建立一个End ...
- C# Socket服务端与客户端通信(包含大文件的断点传输)
步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤: (1)建立一个Socket (2)接收 ...
- java网络编程-单线程服务端与客户端通信
该服务器一次只能处理一个客户端请求;p/** * 利用Socket进行简单服务端与客户端连接 * 这是服务端 */public class EchoServer { private ServerSoc ...
- java的服务端与客户端通信(2)
一.Socket连接与HTTP连接 1.1Socket套接字 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信 ...
- java的服务端与客户端通信(1)
一.理解socket 1.1什么是socket? socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络 ...
- 多线程服务端与客户端通信(IO是阻塞的)_02
下面是多线程的;每次服务端接受请求,会创建一个线程专门处理这个请求: 虽然是多线程的,但还是阻塞,相当于单线程处理模式 public class TimeServer { public static ...
- ROS手动编写服务端和客户端service demo(C++)
service demo 原理和 topic 通信方式很像 点击打开链接,因此 1.srv : 进入 service_demo 创建 srv 文件夹,创建 Greeting.srv,将以下代码插入: ...
随机推荐
- android打包library
最近在做开发时,遇到一个需求,就是要自定义一个控件,最后需要将其打包成android library库,然后供以后其他需求使用,由于以前很少打包library,所以这次特地学了下怎么打包. 首先先随便 ...
- 使用python进行新浪微博粉丝爬虫
由于最近没事在学python,正好最近也想趴下新浪微博上边的一些数据,在这里主要爬去的是一个人的粉丝具体信息(微博昵称,个人介绍,地址,通过什么方式进行关注),所以就学以致用,通过python来爬去微 ...
- 从TensorFlow0.12升级到TensorFlow1.13
sudo pip install --upgrade tensorflow-gpu $ sudo pip install --upgrade tensorflow-gpu[sudo] password ...
- java 理解java的三大特性之继承
继承定义了类如何相互关联,共享特性.对于若干个相同或者相识的类,我们可以抽象出他们共有的行为或者属相并将其定义成一个父类或者超类,然后用这些类继承该父类,他们不仅可以拥有父类的属性.方法还可以定义自己 ...
- 2017 ACM区域赛(南宁站) 参赛流水账
day0: 早上四点起床赶飞机,还好没有吵醒室友导致被打死.本来想在飞机上准备一下下周的小测,结果飞机一点都不平稳,只能全程和队友吹逼聊天.下午在宾馆里和johann通关了一部合金弹头,重温了童年的经 ...
- 【转】VC下的Unicode编程
转自http://www.leewei.org/?p=1304 UniCode简述 在Windows下用VC编程,如果编写的程序要在多种语言环境下运行(比如日文.中文.葡萄牙文等),使用VC默认的MB ...
- 一个事半功倍的c#方法 动态注册按钮事件
前几天在网上看见一个制作计算器的c#程序,其中有一个动态注册按钮事件,觉的很有用.于是实际操作了一哈, 确实比较好. 言归正传,下面就来讲讲怎样动态注册按钮事件. 首先,我们需要设置变量来获取点击一个 ...
- 2013暑假江西联合训练赛 -- by jxust_acm 解题报告
第6题是利用周期性求解, 第7题是 (总的序列长度-最长的满足要求的序列长度) 第8题是 设定起点,可以找到最早出现的不满足条件,然后后面都是不满足的,利用队列求解这个过程 大神给的简单,精炼的题解. ...
- 我的JavaScript笔记--数据类型,预编译,闭包
在我们js中存储数据的空间可以分为两种,堆内存和栈内存 堆内存:我们定义的那些引用数据类型的数据都会在堆内存中开辟空间. 栈内存:我们运行的js代码还有我们定义的基本数据类型,都直接在栈内存中存储 ...
- servlet ; basepath ; sendredirected ;
Eclipse 新建 jsp页面里自动生成以下代码: <%String path = request.getContextPath();String basePath = request.get ...