有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准
https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。 https://store.amazingmemo.com/chapterDetail/1685324709017001`
BioClient
package com.itheima.bio;
import java.io.*;
import java.net.Socket;
/**
* @description
* @author: ts
* @create:2021-04-02 11:48
*/
public class BioClient {
public static void main(String[] args) {
Socket socket = null;
BufferedReader in = null;
BufferedWriter out = null;
try {
socket = new Socket("127.0.0.1",8888);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("准备向服务端写数据!");
//向服务端写数据
out.write("hello server , i am client ! \n");//注意别丢 \n 因为服务端是readLine
out.flush();
//接收来自服务端的数据
String line = in.readLine();
System.out.println("成功接收到来自服务端的数据:"+line);
} catch (IOException e) {
if (in != null) {
try {
in.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
}
}
BioServer
package com.itheima.bio;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class BioServer6 {
public static void main(String[] args) throws IOException {
// 基于ServerSocket
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端绑定端口,开启监听");
while (true) {
Socket socket = serverSocket.accept();//Socket代表了一个客户端链接,accept是阻塞的
System.out.println("接受了一个客户端链接:socket="+socket);
new Thread(new ServerHandler6(socket)).start();
}
}
static class ServerHandler6 implements Runnable {
private final Socket socket;
public ServerHandler6(Socket socket) {
this.socket =socket;
}
@Override
public void run() {
try {
//负责读写数据,业务操作
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
while (true) {
String line = reader.readLine();
System.out.println("收到了来自客户端的数据:"+line);
// bus
//向客户端写数据
writer.write("hello bio client,i am bioserver \n");
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
NioClient
package com.itheima.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.Set;
import java.util.concurrent.TimeUnit;
/**
* @description
* @author: ts
* @create:2021-04-02 15:24
*/
public class NioClient {
public static void main(String[] args) {
try {
//1、窗口客户端SocketChannel,绑定客户端本地地址(不选默认随机分配一个可用地址)
SocketChannel socketChannel = SocketChannel.open();
//2、设置非阻塞模式,
socketChannel.configureBlocking(false);
//3、创建Selector
Selector selector = Selector.open();
//3、创建Reactor线程
new Thread(new SingleReactorClient(socketChannel,selector)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class SingleReactorClient implements Runnable{
private final SocketChannel socketChannel;
private final Selector selector;
public SingleReactorClient(SocketChannel socketChannel, Selector selector) {
this.socketChannel = socketChannel;
this.selector = selector;
}
public void run() {
try {
//连接服务端
doConnect(socketChannel,selector);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
//5、多路复用器执行多路复用程序
while (true) {
try {
selector.select(1000);
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
processKey(selectionKey);
iterator.remove();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void doConnect(SocketChannel sc, Selector selector) throws IOException {
System.out.println("客户端成功启动,开始连接服务端");
//3、连接服务端
boolean connect = sc.connect(new InetSocketAddress("127.0.0.1", 8888));
//4、将socketChannel注册到selector并判断是否连接成功,连接成功监听读事件,没有继续监听连接事件
System.out.println("connect="+connect);
if (connect) {
sc.register(selector, SelectionKey.OP_READ);
System.out.println("客户端成功连上服务端,准备发送数据");
//开始进行业务处理,向服务端发送数据
doService(sc);
}else {
sc.register(selector,SelectionKey.OP_CONNECT);
}
}
private void processKey(SelectionKey key) throws IOException {
if (key.isValid()) {
//6、根据准备就绪的事件类型分别处理
if (key.isConnectable()) {//服务端可连接事件准备就绪
SocketChannel sc = (SocketChannel) key.channel();
if (sc.finishConnect()) {
//6.1、向selector注册可读事件(接收来自服务端的数据)
sc.register(selector,SelectionKey.OP_READ);
//6.2、处理业务 向服务端发送数据
doService(sc);
}else {
//连接失败,退出
System.exit(1);
}
}
if (key.isReadable()) {//读事件准备继续
//6.1、读服务端返回的数据
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer readBufer = ByteBuffer.allocate(1024);
int readBytes = sc.read(readBufer);
//前面设置过socketChannel是非阻塞的,故要通过返回值判断读取到的字节数
if (readBytes > 0) {
readBufer.flip();//读写模式切换
byte[] bytes = new byte[readBufer.remaining()];
readBufer.get(bytes);
String msg = new String(bytes,"utf-8");
//接收到服务端返回的数据后进行相关操作
doService(msg);
}else if (readBytes < 0) {
//值为-1表示链路通道已经关闭
key.cancel();
sc.close();
}else {
//没读取到数据,忽略
}
}
}
}
private static void doService(SocketChannel socketChannel) throws IOException {
System.out.println("客户端开始向服务端发送数据:");
//向服务端发送数据
byte[] bytes = "hello nioServer,i am nioClient !".getBytes();
ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
writeBuffer.put(bytes);
writeBuffer.flip();
socketChannel.write(writeBuffer);
}
private String doService(String msg) {
System.out.println("成功接收来自服务端响应的数据:"+msg);
return "";
}
}
NioServer
package com.itheima.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.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
public class NioServer6 {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
// 开启端口监听
serverSocketChannel.socket().bind(new InetSocketAddress(8888));
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
// 开启seclector程序即可
new Thread(new SingleReactor6(selector)).start();;
}
static class SingleReactor6 implements Runnable{
private final Selector selector;
public SingleReactor6(Selector selector) {
this.selector = selector;
}
@Override
public void run() {
//开启多路复用程序
while (true) {
// 检测
try {
int select = selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
processSelectedKey(selectionKey);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void processSelectedKey(SelectionKey selectionKey) throws IOException {
if (selectionKey.isValid()) {
//按照事件类型进行区分
if (selectionKey.isAcceptable()) {
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ );
}
if (selectionKey.isReadable()) { // 有数据
SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.read(buffer);
// 从buf中拿到数据
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String msg = new String(bytes, Charset.defaultCharset());
System.out.println("收到了来自客户端的数据:"+msg);
//
buffer.clear();
buffer.put("hello nioclient,im nioserver".getBytes(StandardCharsets.UTF_8));
buffer.flip();
socketChannel.write(buffer);
}
}
}
}
}
本文是原创文章,采用 CC BY-NC-SA 4.0 协议,完整转载请注明来自 小朱
评论
隐私政策
0/500
滚动到此处加载评论...


