本文开发语言基于Java 代码参考SocketServer
目录
OIO
OIO: Old IO or Blocking IO
Sync
vim OIOServer.java
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class OIOServer {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(10001);
System.out.println("server start");
while (true) {
Socket socket = server.accept();
System.out.println("a client connected");
handler(socket);
}
}
public static void handler(Socket socket) {
try {
byte[] bytes = new byte[1024];
InputStream inputStream = socket.getInputStream();
while (true) {
int read = inputStream.read(bytes);
if (read != -1) {
System.out.println(new String(bytes, 0, read).trim());
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
System.out.println("a client closed");
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
# server
javac OIOServer.java && java OIOServer
# client 1
telnet 127.0.0.1 10001
# client 2
telnet 127.0.0.1 10001
# server
server start
a client connected
hello
world
# client 1
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
world
# client 2
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Mac OS安装telnet: brew install telnet
Async
vim OIOServer.java
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OIOServer {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(10001);
System.out.println("server start");
while (true) {
final Socket socket = server.accept();
System.out.println("a client connected");
newCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
handler(socket);
}
});
}
}
public static void handler(Socket socket) {
try {
byte[] bytes = new byte[1024];
InputStream inputStream = socket.getInputStream();
while (true) {
int read = inputStream.read(bytes);
if (read != -1) {
System.out.println(new String(bytes, 0, read));
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
System.out.println("a client closed");
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
# server
javac OIOServer.java && java OIOServer
# client 1
telnet 127.0.0.1 10001
# client 2
telnet 127.0.0.1 10001
# server
server start
a client connected
hello
world
a client connected
hello
world
# client 1
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
world
# client 2
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
world
NIO
NIO: New IO
vim NIOServer.java
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;
public class NIOServer {
private Selector selector;
public void init(int port) throws IOException {
ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
server.socket().bind(new InetSocketAddress(port));
this.selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
}
public void listen() throws IOException {
System.out.println("server start");
while (true) {
selector.select();
Iterator<?> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
iterator.remove();
if (key.isAcceptable()) {
handlerAccept(key);
} else if (key.isReadable()) {
handelerRead(key);
}
}
}
}
public void handlerAccept(SelectionKey key) throws IOException {
System.out.println("a client connected");
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel channel = server.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
}
public void handelerRead(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int read = channel.read(buffer);
if (read != -1) {
String message = new String(buffer.array()).trim();
System.out.println(message);
} else {
System.out.println("a client closed");
key.cancel();
}
}
public static void main(String[] args) throws Exception {
NIOServer server = new NIOServer();
server.init(10001);
server.listen();
}
}
# server
javac NIOServer.java && java NIOServer
# client 1
telnet 127.0.0.1 10001
# client 2
telnet 127.0.0.1 10001
# server
server start
a client connected
hello
world
a client connected
hello
world
# client 1
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
world
# client 2
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
world
小结
-
OIO: Number of threads = Number of clients/sockets active
-
NIO: Number of threads < Number of clients/sockets active
OIO餐厅一个服务员(thread)服务一个客人(client) 而NIO餐厅一个服务员(thread)服务多个客人(clients)
网友评论