java BIO,NIO在单服务器,多客户端通信上的应用

1.BIO,即传统的阻塞式io方式
下面是具体的例子:
server:

package 多线程实现socket阻塞式通信;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author wangpei
 * @version 创建时间:2017年7月19日 上午9:05:58 类说明
 */
public class Server {
    private static int PORT = 8888;
    private static String IP = "127.0.0.1";

    public static void main(String[] args) {
        try {
            ServerSocket server = new ServerSocket(PORT);
            while (true) {
                Socket socket = server.accept();
                // ExecutorService cachedThreadPool =
                // Executors.newCachedThreadPool();
                // cachedThreadPool.execute(new ServerThread(socket));//线程池的实现方式
                new ServerThread(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

class ServerThread extends Thread {
    private Socket socket = null;
    private InputStream in = null;
    private OutputStream out = null;
    private DataInputStream read = null;
    private DataOutputStream write = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            read = new DataInputStream(socket.getInputStream());
            System.out.println("客户端发送的请求为" + read.readUTF());
            write = new DataOutputStream(socket.getOutputStream());
            write.writeUTF("你好,clent");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (Exception e) {
                    socket = null;
                    System.out.println("服务端 finally 异常:" + e.getMessage());
                }
            }
        }
    }

}

client:

package 多线程实现socket阻塞式通信;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * @author wangpei
 * @version 创建时间:2017年7月19日 上午9:06:11 类说明
 */
public class Client {
    private static int PORT = 8888;
    private static String IP = "127.0.0.1";
    private static Socket socket = null;
    private InputStream in = null;
    private OutputStream out = null;
    private static DataInputStream read = null;
    private static DataOutputStream write = null;

    public static void main(String[] args) {
        try {
            socket = new Socket(IP, PORT);
            write = new DataOutputStream(socket.getOutputStream());
            write.writeUTF("你好,服务器");
            read = new DataInputStream(socket.getInputStream());
            System.out.println("服务器发送过来的消息是" + read.readUTF());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            if (socket != null) {
                try {
                    socket.close();
                } catch (Exception e) {
                    socket = null;
                    System.out.println("服务端 finally 异常:" + e.getMessage());
                }
            }

        }

    }

}

总结:BIO主要是通过服务器端循环接收客户端的请求,然后对每一个客户端客户端的请求启动一个线程来进行处理。

为什么称为阻塞式通信:

<1>Server端在接收Client的连接请求时,执行Socket socket = server.accept();,若此时无客户端请求,进入阻塞状态,等待客户端请求。

<2>输入流的阻塞,线程从socket的输入流中读入数据时,若没有足够的数据就会进入阻塞状态,直至有足够的数据,或者达到输入流的末尾,或者出现了异常,才从输入流返回或者异常中断。
<3>线程向输出流写入数据时。

2.NIO,非阻塞式io