Server Status

First, the server status - Busy

Each client needs to wait for the server double-pass

Two-way: the client sends data to the server of the receiving channel

Two-way: the server returns the message transmission channels

Because each channel blockage can only be used to achieve asynchronous thread

 

Second, the number of server threads

A client: the double pass -> 2 threads

client n: 2n threads

The actual number of threads the server: 2n + (when the server creates a thread, the thread garbage collection, listen for client socket threads, the thread forward to reading the contents)

 

Third, the test server

Want to test the server, the server needs to pressure. Server for client connections, send, forward place. N may be sent by creating a client, and the real-time message to the client, then pressure state test server.

 

Fourth, test code

package net.qiujuer.lesson.sample.client;

import net.qiujuer.lesson.sample.client.bean.ServerInfo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 这个测试类应该写什么东西呢?
 * 首先,需要测试服务器的性能,所以需要压力测试。需要进行构建非常多的客户端,并且连接到服务器端。
 * 然后使用客户端频繁地发送信息,测试服务器的压力状态。
 * 1、通过UDP拿到服务器信息
 * 2、开始循环建立1000个客户端,如果连接成功加到连接池
 * 3、当键盘输入任何内容后每隔1s对每个连接的客户端进行输出的操作
 * 4、当键盘再次输入任何内容后进行结束操作
 */
public class ClientTest {
    private static boolean done;
    public static void main(String[] args) throws IOException {
        ServerInfo info = UDPSearcher.searchServer(10000);
        System.out.println("Server:"+info);
        if(info == null){
            return;
        }

        //当前连接数量
        int size = 0;
        List<TCPClient> tcpClients = new ArrayList<>();
        for(int i=0;i<1000;i++){
            try{
                TCPClient tcpClient = TCPClient.startWith(info);
                if(tcpClient==null){
                    System.out.println("连接异常");
                }
                tcpClients.add(tcpClient);
                System.out.println("连接成功:"+(++size));
            }catch (IOException e){
                System.out.println("连接异常");
            }

            //当进行循环的时候,必须等待一点时间,因为服务器默认有阈值。当当前正在连接的客户端达到50以上,那么就会拒绝后面等待连接的客户端
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.in.read();
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    while (!done){
                        for(TCPClient tcpClient:tcpClients){
                            tcpClient.send("Hello~~~");
                        }
                        try {
                            Thread.sleep(1000);
                        }catch (InterruptedException e){
                            e.printStackTrace();
                        }
                    }
                }
            };

            Thread thread = new Thread(runnable);
            thread.start();

            System.in.read();

            //等待线程完成
            done = true;
            try{
                thread.join();
            }catch (Exception e){
                e.printStackTrace();
            }

            //客户端结束操作
            for(TCPClient tcpClient : tcpClients){
                tcpClient.exit();
            }
        }
    }
}

 

package net.qiujuer.lesson.sample.client;


import net.qiujuer.lesson.sample.client.bean.ServerInfo;
import net.qiujuer.library.clink.utils.CloseUtils;

import java.io.*;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

public class TCPClient {
    private final Socket socket;
    private final ReadHandler readHandler;
    private final PrintStream printStream;

    public TCPClient(Socket socket,ReadHandler readHandler) throws IOException {
        this.socket = socket;
        this.readHandler = readHandler;
        this.printStream = new PrintStream(socket.getOutputStream());
    }

    public void exit(){
        readHandler.exit();
        CloseUtils.close(printStream);
        CloseUtils.close(socket);
    }

    public void send(String msg){
        printStream.println(msg);
    }

    public static TCPClient startWith(ServerInfo info) throws IOException {
        Socket socket = new Socket();
        // 超时时间
        socket.setSoTimeout(3000);

        // 连接本地,端口2000;超时时间3000ms
        socket.connect(new InetSocketAddress(Inet4Address.getByName(info.getAddress()), info.getPort()), 3000);

        System.out.println("已发起服务器连接,并进入后续流程~");
        System.out.println("客户端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());
        System.out.println("服务器信息:" + socket.getInetAddress() + " P:" + socket.getPort());

        try {
            ReadHandler readHandler = new ReadHandler(socket.getInputStream());
            readHandler.start();

            return new TCPClient(socket,readHandler);
        } catch (Exception e) {
            System.out.println("连接异常");
            CloseUtils.close(socket);
        }

       return null;
    }



    static class ReadHandler extends Thread {
        private boolean done = false;
        private final InputStream inputStream;

        ReadHandler(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        @Override
        public void run() {
            super.run();
            try {
                // 得到输入流,用于接收数据
                BufferedReader socketInput = new BufferedReader(new InputStreamReader(inputStream));

                do {
                    String str;
                    try {
                        // 客户端拿到一条数据
                        str = socketInput.readLine();
                    } catch (SocketTimeoutException e) {
                        continue;
                    }
                    if (str == null) {
                        System.out.println("连接已关闭,无法读取数据!");
                        break;
                    }
                    // 打印到屏幕
                    System.out.println(str);
                } while (!done);
            } catch (Exception e) {
                if (!done) {
                    System.out.println("连接异常断开:" + e.getMessage());
                }
            } finally {
                // 连接关闭
                CloseUtils.close(inputStream);
            }
        }

        void exit() {
            done = true;
            CloseUtils.close(inputStream);
        }
    }
}

 

Published 174 original articles · won praise 115 · views 830 000 +

Guess you like

Origin blog.csdn.net/nicolelili1/article/details/103982218