初级程序员不得不知道的东西

tcp的三次握手和四次挥手

 tcp的十种状态

Java中的基于tcp协议的socket通信(服务端)

Tcp服务端(第一个版本)

/**
 * Socket的服务端
 *
 *当前程序有弊端   只能为1个客户端提供服务
 *
 */
public class MyServerSocket01 {
    /**
     * 程序的执行入口
     *
     * @param args 传递的参数
     */
    public static void main(String[] args) throws Exception {

        //创建服务端的Socket对象
        ServerSocket serverSocket = new ServerSocket();
        //服务端绑定端口
        serverSocket.bind(new InetSocketAddress(8899));
        //监听客户端的连接(阻塞的方法),返回的是当前连接到服务器的客户端的对象
        Socket socket = serverSocket.accept();
        System.out.println("有客户端" + socket.getRemoteSocketAddress() + "连接到服务器了.....");
        InputStream inputStream = socket.getInputStream();
        //读数据
        byte[] buf = new byte[2];
        int len;
        //调用read方法返回阻塞,当没有数据时会阻塞,并不会返回-1
        while ((len = inputStream.read(buf)) != -1) {
            String str = new String(buf, 0, len);
            System.out.println(str);
        }
    }
}

Tcp服务端(第二个版本)

/**
 * Socket的服务端
 * 当前程序有弊端   只能为一个客户端提供服务,只不过一个客户端断开连接之后其他的客户端才能进来
 */
public class MyServerSocket02 {
    /**
     * 程序的执行入口
     *
     * @param args 传递的参数
     */
    public static void main(String[] args) throws Exception {
        //创建服务端的Socket对象
        ServerSocket serverSocket = new ServerSocket();
        //服务端绑定端口
        serverSocket.bind(new InetSocketAddress(8899));
        while (true) {
            //监听客户端的连接(阻塞的方法),返回的是当前连接到服务器的客户端的对象
            Socket socket = serverSocket.accept();
            System.out.println("有客户端" + socket.getRemoteSocketAddress() + "连接到服务器了.....");
            InputStream inputStream = socket.getInputStream();
            //读数据
            byte[] buf = new byte[2];
            int len;
            //调用read方法返回阻塞,当没有数据时会阻塞,并不会返回-1
            while ((len = inputStream.read(buf)) != -1) {
                String str = new String(buf, 0, len);
                System.out.println(str);
            }
        }
    }
}

Tcp服务端(第三个版本)

/**
 * Socket的服务端
 * 当前程序有弊端   每次一个客户端进来之后都会创建一个线程去处理连接任务,但有大量的客户端连接到服务器的话就会有大量的线程创建,线程的创建和上下文的切换也是非常耗费时间和资源的
 */
public class MyServerSocket02 {
    /**
     * 程序的执行入口
     *
     * @param args 传递的参数
     */
    public static void main(String[] args) throws Exception {
        //创建服务端的Socket对象
        ServerSocket serverSocket = new ServerSocket();
        //服务端绑定端口
        serverSocket.bind(new InetSocketAddress(8899));
        while (true) {
            //监听客户端的连接(阻塞的方法),返回的是当前连接到服务器的客户端的对象
            Socket socket = serverSocket.accept();
            //每次有新的客户端连接到服务器之后都会启动线程来执行
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("有客户端" + socket.getRemoteSocketAddress() + "连接到服务器了.....");
                    InputStream inputStream = null;
                    try {
                        inputStream = socket.getInputStream();
                        //读数据
                        byte[] buf = new byte[2];
                        int len;
                        //调用read方法返回阻塞,当没有数据时会阻塞,并不会返回-1
                        while ((len = inputStream.read(buf)) != -1) {
                            String str = new String(buf, 0, len);
                            System.out.println(str);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

Tcp服务端(第四个版本)

/**
 * Socket的服务端
 * 当前程序有弊端   有两个阻塞  accept  read,其中accept我们就无法解决,但是read阻塞可以解决的(NIO)
 */
public class MyServerSocket04 {
    /**
     * 程序的执行入口
     *
     * @param args 传递的参数
     */
    public static void main(String[] args) throws Exception {
        //创建线程池对象(线程池的大小是本机的cpu可用的核数)
        ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        //创建服务端的Socket对象
        ServerSocket serverSocket = new ServerSocket();
        //服务端绑定端口
        serverSocket.bind(new InetSocketAddress(8899));
        while (true) {
            //监听客户端的连接(阻塞的方法),返回的是当前连接到服务器的客户端的对象
            Socket socket = serverSocket.accept();
            //每次有新的客户端连接到服务器之后都会启动线程来执行
            threadPool.execute(new Runnable() {
                @Override
                public void run() {

                    System.out.println("有客户端" + socket.getRemoteSocketAddress() + "连接到服务器了.....");
                    InputStream inputStream = null;
                    try {
                        inputStream = socket.getInputStream();
                        //读数据
                        byte[] buf = new byte[2];
                        int len;
                        //调用read方法返回阻塞,当没有数据时会阻塞,并不会返回-1
                        while ((len = inputStream.read(buf)) != -1) {
                            String str = new String(buf, 0, len);
                            System.out.println(str);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43087450/article/details/84311412