從bio到nio到netty實現(xiàn)原理淺析
點擊上方藍色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達
public class SocketServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8888);
System.out.println("服務(wù)器已經(jīng)啟動!");
// 接收客戶端發(fā)送的信息
Socket socket = server.accept();
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while ((info = br.readLine()) != null) {
System.out.println(info);
}
// 向客戶端寫入信息
OutputStream os = socket.getOutputStream();
String str = "歡迎登陸到server服務(wù)器!";
os.write(str.getBytes());
// 關(guān)閉文件流
os.close();
br.close();
is.close();
socket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Bio {
public static void main(String[] args) {
ServerSocket server = new ServerSocket(8888);
System.out.println("服務(wù)器已經(jīng)啟動!");
// 接收客戶端發(fā)送的信息
while(true){
Socket socket = null;
try {
socket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
new Thread(() ->{
try {
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while ((info = br.readLine()) != null) {
System.out.println(info);
}
// 向客戶端寫入信息
OutputStream os = socket.getOutputStream();
String str = "歡迎登陸到server服務(wù)器!";
os.write(str.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
}
public class Nio {
// 本地字符集
private static final String LocalCharSetName = "UTF-8";
// 本地服務(wù)器監(jiān)聽的端口
private static final int Listenning_Port = 8888;
// 緩沖區(qū)大小
private static final int Buffer_Size = 1024;
// 超時時間,單位毫秒
private static final int TimeOut = 3000;
public static void main(String[] args) throws IOException {
// 創(chuàng)建一個在本地端口進行監(jiān)聽的服務(wù)Socket信道.并設(shè)置為非阻塞方式
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.socket().bind(new InetSocketAddress(Listenning_Port));
serverChannel.configureBlocking(false);
// 創(chuàng)建一個選擇器并將serverChannel注冊到它上面
Selector selector = Selector.open();
//設(shè)置為客戶端請求連接時,默認客戶端已經(jīng)連接上
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// 輪詢監(jiān)聽key,select是阻塞的,accept()也是阻塞的
if (selector.select(TimeOut) == 0) {
System.out.println(".");
continue;
}
// 有客戶端請求,被輪詢監(jiān)聽到
Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
while (keyIter.hasNext()) {
SelectionKey key = keyIter.next();
if (key.isAcceptable()) {
SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept();
clientChannel.configureBlocking(false);
//意思是在通過Selector監(jiān)聽Channel時對讀事件感興趣
clientChannel.register(selector, SelectionKey.OP_READ,
ByteBuffer.allocate(Buffer_Size));
}
else if (key.isReadable()) {
SocketChannel clientChannel = (SocketChannel) key.channel();
// 接下來是java緩沖區(qū)io操作,避免io堵塞
ByteBuffer buffer = (ByteBuffer) key.attachment();
buffer.clear();
long bytesRead = clientChannel.read(buffer);
if (bytesRead == -1) {
// 沒有讀取到內(nèi)容的情況
clientChannel.close();
} else {
// 將緩沖區(qū)準(zhǔn)備為數(shù)據(jù)傳出狀態(tài)
buffer.flip();
// 將獲得字節(jié)字符串(使用Charset進行解碼)
String receivedString = Charset
.forName(LocalCharSetName).newDecoder().decode(buffer).toString();
System.out.println("接收到信息:" + receivedString);
String sendString = "你好,客戶端. 已經(jīng)收到你的信息" + receivedString;
buffer = ByteBuffer.wrap(sendString.getBytes(LocalCharSetName));
clientChannel.write(buffer);
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
keyIter.remove();
}
}
}
}
public class Netty {
public void start(int port) throws Exception
{
ServerBootstrap strap = new ServerBootstrap();
//主線程
EventLoopGroup bossGroup = new NioEventLoopGroup();
//從線程
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
strap.group(bossGroup, workerGroup).
//主線程監(jiān)聽通道
channel(NioServerSocketChannel.class).
option(ChannelOption.SO_BACKLOG, 1024).
//定義從線程的handler鏈,責(zé)任鏈模式
childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new NettyServerHandler());
}
});
ChannelFuture future=strap.bind(port).sync();
future.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
System.out.println("start server");
new Netty().start(8000);
}
}
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。
本文鏈接:
https://blog.csdn.net/qq_20597727/article/details/80789272
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長按上方微信二維碼 2 秒
感謝點贊支持下哈 
評論
圖片
表情




