first commit

This commit is contained in:
2023-09-07 00:56:03 +08:00
commit c0ca154d31
718 changed files with 56107 additions and 0 deletions

3
io-study-master/io-study/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/.idea
/*.iml
/target

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>io-study</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- netty -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.35.Final</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,60 @@
package bio;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @description: bio演示代码
* @param
* @return
* @author lld
*/
public class SocketServer {
//1.0 服务端在处理完第一个客户端的所有事件之前,无法为其他客户端提供服务。
//2.0 会产生大量空闲线程,浪费服务器资源。
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9001);
while (true) {
System.out.println("等待连接..");
//阻塞方法
Socket clientSocket = serverSocket.accept();
System.out.println("有客户端连接了..");
// handler(clientSocket);
new Thread(new Runnable() {
@Override
public void run() {
try {
handler(clientSocket);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
private static void handler(Socket clientSocket) throws Exception {
// while (true){
byte[] bytes = new byte[1024];
System.out.println("准备read..");
//接收客户端的数据,阻塞方法,没有数据可读时就阻塞
int read = clientSocket.getInputStream().read(bytes);
System.out.println("read完毕。。");
if (read != -1) {
// int i = (int) (1 + Math.random() * (10 - 1 + 1));
// System.out.println("收到客户端: " + Thread.currentThread().getName() + "收到了数据开始休眠");
// Thread.sleep(i*1000L);
System.out.println("接收到客户端的数据:" + new String(bytes, 0, read));
}
// clientSocket.getOutputStream().write("HelloClient".getBytes());
// clientSocket.getOutputStream().flush();
// }
}
}

View File

@@ -0,0 +1,14 @@
package netty.base;
import netty.base.server.DiscardServer;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class Starter {
public static void main(String[] args) throws Exception {
new DiscardServer(9001).run();
}
}

View File

@@ -0,0 +1,33 @@
package netty.base.handler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("有客户端连接了");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf out = (ByteBuf) msg;
String data = out.toString(CharsetUtil.UTF_8);
System.out.println(data);
short length = (short) data
.getBytes().length;
ByteBuf byteBuf = Unpooled.directBuffer(8);
byteBuf.writeShort(length);
byteBuf.writeBytes(data.getBytes());
ctx.writeAndFlush(byteBuf);
}
}

View File

@@ -0,0 +1,66 @@
package netty.base.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import netty.base.handler.DiscardServerHandler;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class DiscardServer {
private int port;
public DiscardServer(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1); //线程池
EventLoopGroup workerGroup = new NioEventLoopGroup();//
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(
1024,0,
4,0,4
));
// ch.pipeline().addLast(new LengthFieldPrepender(2));
// ch.pipeline().addLast(new StringDecoder());
// ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new DiscardServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
// Bind and start to accept incoming connections.
System.out.println("tcp start success");
ChannelFuture f = b.bind(port).sync(); // (7)
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}

View File

@@ -0,0 +1,29 @@
package netty.bytebuf;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public class NettyByteBuf {
public static void main(String[] args) {
// 创建byteBuf对象该对象内部包含一个字节数组byte[10]
ByteBuf byteBuf = Unpooled.buffer(10);
System.out.println("byteBuf=" + byteBuf);
for (int i = 0; i < 8; i++) {
byteBuf.writeByte(i);
}
System.out.println("byteBuf=" + byteBuf);
for (int i = 0; i < 5; i++) {
System.out.println(byteBuf.getByte(i));
}
System.out.println("byteBuf=" + byteBuf);
for (int i = 0; i < 5; i++) {
System.out.println(byteBuf.readByte());
}
System.out.println("byteBuf=" + byteBuf);
}
}

View File

@@ -0,0 +1,19 @@
package netty.chat;
import netty.chat.server.DiscardServer;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class Starter {
// line
// header
// body
public static void main(String[] args) throws Exception {
new DiscardServer(9001).run();
}
}

View File

@@ -0,0 +1,67 @@
package netty.chat.handler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.HashSet;
import java.util.Set;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
static Set<Channel> channelList = new HashSet<>();
// @Override
// public void channelActive(ChannelHandlerContext ctx) throws Exception {
// //通知其他人 我上线了
// channelList.forEach(e->{
// e.writeAndFlush("[客户端]" + ctx.channel().remoteAddress() + "上线了");
// });
//
// channelList.add(ctx.channel());
// }
//网络调试助手 -> 服务端
//?直接发送!?
//网络调试助手 -> 操作系统 -> 网络 -> 对方操作系统 -> 9000找到对应进程我们的服务端
//!字符串
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String message = (String) msg;
// Charset gbk = Charset.forName("GBK");
System.out.println("收到数据:" + message);
// 分发给聊天室内的所有客户端
// 通知其他人 我上线了
channelList.forEach(e->{
if(e == ctx.channel()){
e.writeAndFlush("[自己] " + message);
}else{
e.writeAndFlush("[客户端] " +ctx.channel().remoteAddress()+"" + message);
}
});
}
/**
* @description: channel 处于不活跃的时候会调用
* @param
* @return void
* @author lld
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//通知其他客户端 我下线了
channelList.remove(ctx.channel());
//通知其他人 我上线了
channelList.forEach(e->{
e.writeAndFlush("[客户端]" + ctx.channel().remoteAddress() + "下线了");
});
}
}

View File

@@ -0,0 +1,69 @@
package netty.chat.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import netty.chat.handler.DiscardServerHandler;
import java.nio.charset.Charset;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class DiscardServer {
private int port;
public DiscardServer(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1); //线程池
EventLoopGroup workerGroup = new NioEventLoopGroup();//
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
Charset gbk = Charset.forName("utf-8");
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, Unpooled.copiedBuffer("_"
.getBytes())));
ch.pipeline().addLast("encoder", new StringEncoder(gbk));//out
ch.pipeline().addLast("decoder", new StringDecoder(gbk));//in
ch.pipeline().addLast(new DiscardServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
// Bind and start to accept incoming connections.
System.out.println("tcp start success");
ChannelFuture f = b.bind(port).sync(); // (7)
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}

View File

@@ -0,0 +1,22 @@
package netty.heaetbeat;
import netty.heaetbeat.server.DiscardServer;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class Starter {
//2
//
//0-2 + 1 = 3 ___3 //5
public static void main(String[] args) throws Exception {
new DiscardServer(9001).run();
}
}

View File

@@ -0,0 +1,32 @@
package netty.heaetbeat.handler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class HeartbeatHandler extends ChannelInboundHandlerAdapter {
int readTimeOut = 0;
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
IdleStateEvent event = (IdleStateEvent) evt;
if(event.state() == IdleState.READER_IDLE){
readTimeOut++;
}
if(readTimeOut >= 3){
System.out.println("超时超过3次断开连接");
ctx.close();
}
// System.out.println("触发了:" + event.state() + "事件");
}
}

View File

@@ -0,0 +1,60 @@
package netty.heaetbeat.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import netty.heaetbeat.handler.HeartbeatHandler;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class DiscardServer {
private int port;
public DiscardServer(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1); //线程池
EventLoopGroup workerGroup = new NioEventLoopGroup();//
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new IdleStateHandler(3,0,0));
ch.pipeline().addLast(new HeartbeatHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
// Bind and start to accept incoming connections.
System.out.println("tcp start success");
ChannelFuture f = b.bind(port).sync(); // (7)
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}

View File

@@ -0,0 +1,15 @@
package netty.my;
import netty.my.server.DiscardServer;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class Starter {
public static void main(String[] args) throws Exception {
new DiscardServer(9001).run();
}
}

View File

@@ -0,0 +1,34 @@
package netty.my.codec;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class MyDecodecer extends ByteToMessageDecoder {
//数据长度 + 数据
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if(in.readableBytes() < 4){
return;
}
//数据长度 4 + 10000 9999
int i = in.readInt();
if(in.readableBytes() < i){
in.resetReaderIndex();
return;
}
byte[] data = new byte[i];//10000
in.readBytes(data);
System.out.println(new String(data));
in.markReaderIndex();//10004
}
}

View File

@@ -0,0 +1,43 @@
package netty.my.handler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.HashSet;
import java.util.Set;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
static Set<Channel> channelList = new HashSet<>();
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
}
//网络调试助手 -> 服务端
//?直接发送!?
//网络调试助手 -> 操作系统 -> 网络 -> 对方操作系统 -> 9000找到对应进程我们的服务端
//!字符串
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
}
/**
* @description: channel 处于不活跃的时候会调用
* @param
* @return void
* @author lld
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
}
}

View File

@@ -0,0 +1,62 @@
package netty.my.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import netty.my.codec.MyDecodecer;
import java.nio.charset.Charset;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class DiscardServer {
private int port;
public DiscardServer(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1); //线程池
EventLoopGroup workerGroup = new NioEventLoopGroup();//
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
Charset gbk = Charset.forName("utf-8");
ch.pipeline().addLast(new MyDecodecer());
// ch.pipeline().addLast(new DiscardServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
// Bind and start to accept incoming connections.
System.out.println("tcp start success");
ChannelFuture f = b.bind(port).sync(); // (7)
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}

View File

@@ -0,0 +1,19 @@
package netty.upload;
import lombok.Data;
/**
* @description:
* @author: lld
* @version: 1.0
*/
@Data
public class FileDto {
private String fileName; //文件名称
private Integer command; // 1请求创建文件 2传输文件
private byte[] bytes; //文件字节;再实际应用中可以使用非对称加密,以保证传输信息安全
}

View File

@@ -0,0 +1,22 @@
package netty.upload;
import netty.upload.server.UploadFileServer;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class Starter {
//请求上传
//创建文件
//将客户端数据写入本地磁盘
//command 4 fileName 4 8
//请求上传 -> 是否能够上传 -> 上传(客户端) -》将客户端数据写入本地磁盘
public static void main(String[] args) throws Exception {
new UploadFileServer(9001).run();
}
}

View File

@@ -0,0 +1,59 @@
package netty.upload.codec;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import netty.upload.FileDto;
import java.util.List;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class UploadFileDecodecer extends ByteToMessageDecoder {
//请求上传
//创建文件
//将客户端数据写入本地磁盘
//command 4 fileName 4 8
//数据长度 + 数据
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if(in.readableBytes() < 8){
return;
}
//command 4
int command = in.readInt();
FileDto fileDto = new FileDto();
int fileNameLen = in.readInt();
if(in.readableBytes() < fileNameLen){
in.resetReaderIndex();
return;
}
byte[] data = new byte[fileNameLen];
in.readBytes(data);
String fileName = new String(data);
fileDto.setCommand(command);
fileDto.setFileName(fileName);
if(command == 2){
int dataLen = in.readInt();
if(in.readableBytes() < dataLen){
in.resetReaderIndex();
return;
}
byte[] fileData = new byte[dataLen];
in.readBytes(fileData);
fileDto.setBytes(fileData);
}
in.markReaderIndex();//10004
out.add(fileDto);
}
}

View File

@@ -0,0 +1,68 @@
package netty.upload.handler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import netty.upload.FileDto;
import java.io.*;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class UploadFileHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(msg instanceof FileDto){
FileDto dto = (FileDto) msg;
if(dto.getCommand() == 1){
//创建文件
File file = new File("C://"+dto.getFileName());
if(!file.exists()){
file.createNewFile();
}
}else if(dto.getCommand() == 2){
//写入文件
save2File("C://"+dto.getFileName(),dto.getBytes());
}
}
}
public static boolean save2File(String fname, byte[] msg){
OutputStream fos = null;
try{
File file = new File(fname);
File parent = file.getParentFile();
boolean bool;
if ((!parent.exists()) &
(!parent.mkdirs())) {
return false;
}
fos = new FileOutputStream(file,true);
fos.write(msg);
fos.flush();
return true;
}catch (FileNotFoundException e){
return false;
}catch (IOException e){
File parent;
return false;
}
finally{
if (fos != null) {
try{
fos.close();
}catch (IOException e) {}
}
}
}
}

View File

@@ -0,0 +1,60 @@
package netty.upload.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import netty.upload.codec.UploadFileDecodecer;
import netty.upload.handler.UploadFileHandler;
/**
* @description:
* @author: lld
* @version: 1.0
*/
public class UploadFileServer {
private int port;
public UploadFileServer(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1); //线程池
EventLoopGroup workerGroup = new NioEventLoopGroup();//
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new UploadFileDecodecer());
ch.pipeline().addLast(new UploadFileHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
// Bind and start to accept incoming connections.
System.out.println("tcp start success");
ChannelFuture f = b.bind(port).sync(); // (7)
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}

View File

@@ -0,0 +1,88 @@
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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
/**
* @description: nio Selector演示代码
* @param
* @return
* @author lld
*/
public class NioSelectorServer {
//BIO
//1.0
// 2 2 1 1 1 1
// 0
// 1 1 2 1 1 1
// 0 0 0 0 0 0
//NIO
//1.0
// 2 2 2 2 2 2
// 0
//2.0
// 2 2 2 2 2 2
// 0
public static void main(String[] args) throws IOException {
int OP_ACCEPT = 1 << 4;
System.out.println(OP_ACCEPT);
// 创建NIO ServerSocketChannel
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(9001));
// 设置ServerSocketChannel为非阻塞
serverSocket.configureBlocking(false);
// 打开Selector处理Channel即创建epoll
Selector selector = Selector.open();
// 把ServerSocketChannel注册到selector上并且selector对客户端accept连接操作感兴趣
SelectionKey selectionKey = serverSocket.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务启动成功");
while (true) {
// 阻塞等待需要处理的事件发生 已注册事件发生后,会执行后面逻辑
selector.select();
// 获取selector中注册的全部事件的 SelectionKey 实例
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
// 遍历SelectionKey对事件进行处理
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
// 如果是OP_ACCEPT事件则进行连接获取和事件注册
if (key.isAcceptable()) {
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = server.accept();
socketChannel.configureBlocking(false);
// 这里只注册了读事件,如果需要给客户端发送数据可以注册写事件
SelectionKey selKey = socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("客户端连接成功");
} else if (key.isReadable()) { // 如果是OP_READ事件则进行读取和打印
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(128);
int len = socketChannel.read(byteBuffer);
// 如果有数据,把数据打印出来
if (len > 0) {
System.out.println(Thread.currentThread().getName() + "接收到消息:" + new String(byteBuffer.array()));
} else if (len == -1) { // 如果客户端断开连接关闭Socket
System.out.println("客户端断开连接");
socketChannel.close();
}
}
//从事件集合里删除本次处理的key防止下次select重复处理
iterator.remove();
}
}
}
}

View File

@@ -0,0 +1,63 @@
package nio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @description: nio演示代码
* @param
* @return
* @author lld
*/
public class NioServer {
// 保存客户端连接
static List<SocketChannel> channelList = new ArrayList<>();
//10w
//1w
//
public static void main(String[] args) throws IOException {
// 创建NIO ServerSocketChannel,与BIO的serverSocket类似
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(9001));
// 设置ServerSocketChannel为非阻塞
serverSocket.configureBlocking(false);
System.out.println("服务启动成功");
while (true) {
// 非阻塞模式accept方法不会阻塞否则会阻塞
// NIO的非阻塞是由操作系统内部实现的底层调用了linux内核的accept函数
SocketChannel socketChannel = serverSocket.accept();
if (socketChannel != null) { // 如果有客户端进行连接
System.out.println("连接成功");
// 设置SocketChannel为非阻塞
socketChannel.configureBlocking(false);
// 保存客户端连接在List中
channelList.add(socketChannel);
}
// 遍历连接进行数据读取 10w - 1000 读写事件
Iterator<SocketChannel> iterator = channelList.iterator();
while (iterator.hasNext()) {
SocketChannel sc = iterator.next();
ByteBuffer byteBuffer = ByteBuffer.allocate(128);
// 非阻塞模式read方法不会阻塞否则会阻塞
int len = sc.read(byteBuffer);
// 如果有数据,把数据打印出来
if (len > 0) {
System.out.println(Thread.currentThread().getName() + " 接收到消息:" + new String(byteBuffer.array()));
} else if (len == -1) { // 如果客户端断开把socket从集合中去掉
iterator.remove();
System.out.println("客户端断开连接");
}
}
}
}
}

View File

@@ -0,0 +1,14 @@
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("127.0.0.1",9001))
for i in range(100):
print(i)
string = "hello1哈_";
body = bytes(string, 'utf-8')
s.sendall(body)

View File

@@ -0,0 +1,21 @@
import uuid
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("127.0.0.1",9001))
data = "哈哈哈asdasdadfasdfasdfa哈123"
print(data)
dataBytes = bytes(data,"utf-8")
dataLen = len(dataBytes)
data_len = dataLen.to_bytes(4, byteorder='big')
# s.sendall(data_len + dataBytes)
for i in range(100):
print(i)
s.sendall(data_len + dataBytes)

View File

@@ -0,0 +1,34 @@
#-*- coding: UTF-8 -*-
import socket,os,struct
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("127.0.0.1",9001))
filepath = "D://natapp.zip"
if os.path.isfile(filepath):
filename = os.path.basename(filepath).encode('utf-8')
# 请求传输文件
command = 1
body_len = len(filename)
fileNameData = bytes(filename)
i = body_len.to_bytes(4, byteorder='big')
c = command.to_bytes(4, byteorder='big')
s.sendall(c + i + fileNameData)
fo = open(filepath,'rb')
while True:
command = 2;
c = command.to_bytes(4, byteorder='big')
filedata = fo.read(1024)
print(len(filedata))
b = len(filedata).to_bytes(4, byteorder='big')
if not filedata:
break
s.sendall(c + i + fileNameData + b + filedata)
fo.close()
#s.close()
else:
print(False)