0

一部のユーザーデータを転送して単純なMySQLテーブルに保存する単純なTCPサーバーを作成しました。2000 を超えるクライアントを次々と実行すると、動作が停止します。実行中に、いくつかIO error java.io.EOFExceptionのエラーが表示される場合があります。しかし、最も重要なことは、私がこれを手に入れることです

 IO error java.net.SocketException: Connection reset
    Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
    at java.lang.Thread.start0(Native Method)
    at java.lang.Thread.start(Unknown Source)
    at Server.main(Server.java:49)

十分なメモリがあるはずですが、スレッドはまだ実行されており、スレッドが終了しないという間違いをどこで犯したのかわかりません。そのため、最大 3900 のスレッドが実行されました。サーバーの一部は次のとおりです。

try {
    // create new socket
    ServerSocket sock = new ServerSocket(port);
    textArea.setText(textArea.getText() + "Server started\n");
    while (true) {
        // accept the connection
            Socket newsock = sock.accept();
        // handle the action
        Thread t = new ThreadHandler(newsock);
            newsock.setSoTimeout(2000); // adding client timeout
        t.start();
        }
    } catch (Exception e) {

本当に簡単だと思います。ソケットの処理方法は次のとおりです。

class ThreadHandler extends Thread {
    private Socket socket;
    private MySQLConnection sqlConnection;

    ThreadHandler(Socket s) {
        socket = s;
        sqlConnection = new MySQLConnection();
    }

    public void run() {
        try {
            DataOutputStream out = new DataOutputStream(
                    socket.getOutputStream());
            DataInputStream in = new DataInputStream(new BufferedInputStream(
                    socket.getInputStream()));
            Server.textArea.append((new Date()) + "\nClient connected IP: " + socket.getInetAddress().toString()+"\n");

            int firstLine = in.readInt(); // get first line for switch

            switch (firstLine) {
            case 0:
                // getting the whole objekt for the database in own lines!
                String name2 = in.readUTF();
                int level2 = in.readInt();
                int kp2 = in.readInt();
                String skill = in.readUTF();

                LeadboardElement element2 = new LeadboardElement();
                element2.setName(name2);
                element2.setLevel(level2);
                element2.setKillPoints(kp2);
                element2.setSkill(skill);
                sqlConnection.saveChaToLeadboard(element2);
                break;
                //case 1 return the top10
###.... shorten here the rest of the cases
                out.close();
            in.close();
            //close this socket
            socket.close();
                    Server.textArea.append("Client disconnected IP: " + socket.getInetAddress().toString()+ "\n" + (new Date())
                            + "\n----------------------------------------------------\n");
            // autoscrolldown
            Server.textArea.setCaretPosition(Server.textArea.getDocument()
                    .getLength());
         } catch (Exception e) {
            System.out.println("IO error " + e);
            try {
                socket.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }finally{
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

saveChaToLeadboard単純に名前レベル kp とスキルを取得し、a を使用するpreparedStatementので、MySQL テーブルに保存します。私はあなたが私を助けてくれることを願っています。どこかに参加する必要があると思いますが、最後に(socket.close()の後)参加しても同じです。

データベースへの保存方法は次のとおりです。

public void saveChaToLeadboard(LeadboardElement element) {
        try {
            // load driver
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(this.databaseURL
                    + DATABASE_NAME, this.user, this.password);
            // insert values into the prep statement
            preparedStatement = connection
                    .prepareStatement(PREP_INSERT_STATEMENT);
            preparedStatement.setString(1, element.getName());
            preparedStatement.setInt(2, element.getLevel());
            preparedStatement.setInt(3, element.getKillPoints());
            if(!element.getSkill().equalsIgnoreCase("")){
                preparedStatement.setString(4, element.getSkill());
            }else{
                preparedStatement.setString(4, null);
            }
            // execute
            preparedStatement.executeUpdate();
            connection.close();

        } catch (Exception e) {
            Server.textArea.append(e.getMessage() + "\n");
            Server.textArea.setCaretPosition(Server.textArea.getDocument()
                    .getLength());
            try {
                connection.close();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }

どうもありがとう!よろしく

4

2 に答える 2