1.IO的基本操作
只线程情况下只能有一个客户端的连接
package xss.netty.basicio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* java 原生的IO处理方式
* IO Server
*/
public class IOMainServerTest {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket=new ServerSocket(9999);
System.out.println("server start.......");
while (true){
// 会阻塞client的连接,只到client的消息处理完
//也就是说一次只能处理一个客户端的请求
Socket socket=serverSocket.accept();
System.out.println("new client connect");
handler(socket);
}
}
public static void handler(Socket socket) {
try{
InputStream inputStream=socket.getInputStream();
byte[] readBytes=new byte[1024];
while(true){
int reads =inputStream.read(readBytes);//阻塞数据的读取
if(reads != -1){
System.out.println("message ->"+new String(readBytes,0,reads));
}else{
break;
}
}
}catch (Exception ex){
ex.printStackTrace();
}finally {
try {
System.out.println("socket closed.");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
可多客户端的同时连接
package xss.netty.basicio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* java 原生的IO处理方式
* 改进之一:服务端可以同时接收多个客户端的请求
*
*/
public class IOMainServerMutliClientTest {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket=new ServerSocket(9999);
System.out.println("server start.......");
ExecutorService executors= Executors.newCachedThreadPool();
while (true){
// 会阻塞client的连接,只到client的消息处理完
//也就是说一次只能处理一个客户端的请求
final Socket socket=serverSocket.accept();
System.out.println("new client connect");
executors.execute(new Runnable() {
public void run() {
handler(socket);
}
});
}
}
public static void handler(Socket socket) {
try{
InputStream inputStream=socket.getInputStream();
byte[] readBytes=new byte[1024];
while(true){
int reads =inputStream.read(readBytes);//阻塞数据的读取
if(reads != -1){
System.out.println("message ->"+new String(readBytes,0,reads));
}else{
break;
}
}
}catch (Exception ex){
ex.printStackTrace();
}finally {
try {
System.out.println("socket closed.");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.NIO的基本操作
package xss.netty.basicio;
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;
/**
* NIO 基本知识点
*/
public class NIOMainServerTest {
//通道的管理,监听客户发送的事件
private Selector selector;
public static void main(String[] args) throws Exception{
NIOMainServerTest serverTest=new NIOMainServerTest();
serverTest.initServer(9999);
serverTest.listen();
System.out.println("main executed.");
}
/**
* 初始化ServerSocket 通道
* @param port
* @throws IOException
*/
public void initServer(int port) throws IOException{
ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
//设置为非阻塞通道
serverSocketChannel.configureBlocking(false);
//绑定端口
serverSocketChannel.socket().bind(new InetSocketAddress(port));
//
this.selector=Selector.open();
//将selector 与 通道进行绑定,并且注册ACCEPT事件
//selector会阻塞监听是否有ACCEPT事件的到达。Selector.select()
serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);
System.out.println("Server init finished with prot="+port);
}
/**
* 轮询监听selector上是否有需要处理的事件
* @throws IOException
*/
public void listen() throws IOException{
System.out.println("start listen...");
while (true){
//当注册的事件到达时,方法返回;否则,该方法会一直阻塞
selector.select();
//获得selector中选中的项的迭代器,选中的项为注册的事件
Iterator iterator=this.selector.selectedKeys().iterator();
while(iterator.hasNext()){
SelectionKey selectionKey=(SelectionKey)iterator.next();
iterator.remove();//删除已选的key,以防重复处理
//处理请求
this.handler(selectionKey);
}
}
}
/**
* 事件类型请求的处理
* @param key
* @throws IOException
*/
public void handler(SelectionKey key) throws IOException{
if(key.isAcceptable()){
//客户端的连接请求事件
handlerAccept(key);
}else if(key.isReadable()){
//处理客户端发送的数据
handelerRead(key);
}
}
public void handlerAccept(SelectionKey key) throws IOException {
ServerSocketChannel serverSocketChannel=(ServerSocketChannel) key.channel();
//建立与客户端连接的通道
SocketChannel channel=serverSocketChannel.accept();
channel.configureBlocking(false);
//给selector 绑定客户端,并且监听客户端发送的请求。即对于服务端来说是可读取到客户端的数据
//请求
channel.register(this.selector,SelectionKey.OP_READ);
System.out.println("New Client connected");
}
public void handelerRead(SelectionKey key) throws IOException {
SocketChannel channel=(SocketChannel)key.channel();
//缓冲区的大小以实际情况来调整
ByteBuffer byteBuffer= ByteBuffer.allocate(1024);
//读取数据, -- 示例客户端最大一次性发送1024
int read=channel.read(byteBuffer);
if(read>0){
String readMsg=new String(byteBuffer.array());
System.out.println("Read message:"+readMsg);
//响应客户端
ByteBuffer outBuffer=ByteBuffer.wrap((readMsg+" is Ok").getBytes());
channel.write(outBuffer);
}else{
System.out.println("client closed.");
key.cancel();
}
}
}
操作系统IO Selector 模型类似