1

私のプログラムは正常に動作し、多くのユーザーがサーバーに接続してコマンドを送信できます。ただし、ユーザーがコマンドを使用してサーバーにスパムを送信すると、サーバーは他のすべてのクライアントをブロックし、サーバーはスパムを送信したクライアント以外のクライアントからのメッセージを受信しません。どうしてこれなの?

TCPAccept接続


    package game.server;

import java.io.IOException;
import java.net.Socket;

public class TCPAcceptConnections implements Runnable
{
    public static Socket clientSocket = null;;
    int clientID = -1;

    public void run()
    {
        while(Main.TCP)
        {
            try
            {
                clientSocket = TCPServer.serverSocket.accept();
                System.out.println("Client Connected.");
                clientID++;

                new TCPClientManager(clientSocket, clientID).run();
            } 
            catch (IOException e)
            {
                System.out.println("Couldn't create client socket.");
                System.exit(-1);
            }
        }
    }
}

TCPClientManager:


    package game.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class TCPClientManager implements Runnable
{
    Socket client;

    int clientID;

    static PrintWriter out;
    static BufferedReader in;
    String inputLine, outputLine;

    boolean destroy = false;

    public TCPClientManager(Socket cs, int id)
    {
        try
        {
            client = cs;
            clientID = id;
            out = new PrintWriter(client.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        } catch(IOException e)
        {
            e.printStackTrace();
        }
    }

    public void run()
    {
        System.out.println("Created TCPManager for client.");
        String command;

        while(!destroy)
        {
            try
            {
                if((command = in.readLine()) != null) //If received something
                {
                    System.out.println("Commad received: " + command);
                        System.out.println(" " + Commands.proccessCommand(command));
                    System.out.println("Command proccessed");
                }
                else
                {
                    client.close();
                    destroy = true;
                }
            } catch (IOException e)
            {
                try
                {
                    client.close();
                } catch (IOException e1)
                {
                    e1.printStackTrace();
                    destroy = true;
                }
                System.out.println("Client lost connection.");
                destroy = true;
            }
        }
        System.out.println("TCPManager for client destroyed.");
    }
}

コマンド:


package game.server;

public class Commands
{
    public static String proccessCommand(String command)
    {
        if(command.equalsIgnoreCase("cp"))
        {
            System.out.println("Creating player...");
                System.out.println("    Retrieved client");
            return "Player Created";
        }
        else
        {
            return "Unkown command: " + command;
        }
    }
}
4

1 に答える 1

1

不明なコマンドを受け取った場合は、それをログに記録して接続を閉じる必要があります。

しかし、もっと深刻な問題があります。nullを読み取ったときに、クライアントハンドラーを停止していません。したがって、クライアントが切断すると、読み取りは永久に無駄に回転します。readLine()がnullを返す場合は、ソケットを閉じてループを終了する必要があります。IOExceptionが発生した場合は、ソケットも閉じる必要があります。

于 2012-10-28T01:06:02.293 に答える