Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java TCP多线程问题_Java_Multithreading_Networking_Tcp - Fatal编程技术网

Java TCP多线程问题

Java TCP多线程问题,java,multithreading,networking,tcp,Java,Multithreading,Networking,Tcp,我的程序运行良好,许多用户可以连接并向服务器发送命令。 但是,当用户使用命令向服务器发送垃圾邮件时,服务器会屏蔽所有其他客户端,并且服务器不会从发送垃圾邮件的客户端以外的客户端接收消息。 为什么会这样 TCPAccept连接 TCPClientManager: 命令: 如果收到未知命令,应记录该命令并关闭连接 但你有一个更严重的问题。当客户端处理程序读取null时,您没有停止它。因此,一旦客户端断开连接,读取将永远徒劳地旋转。如果readLine()返回null,则必须关闭套接字并退出循环

我的程序运行良好,许多用户可以连接并向服务器发送命令。 但是,当用户使用命令向服务器发送垃圾邮件时,服务器会屏蔽所有其他客户端,并且服务器不会从发送垃圾邮件的客户端以外的客户端接收消息。 为什么会这样

TCPAccept连接


TCPClientManager:


命令:



如果收到未知命令,应记录该命令并关闭连接


但你有一个更严重的问题。当客户端处理程序读取null时,您没有停止它。因此,一旦客户端断开连接,读取将永远徒劳地旋转。如果readLine()返回null,则必须关闭套接字并退出循环。如果您收到任何IOException,您还必须关闭套接字。

如果您收到未知命令,您应该记录该命令并关闭连接


但你有一个更严重的问题。当客户端处理程序读取null时,您没有停止它。因此,一旦客户端断开连接,读取将永远徒劳地旋转。如果readLine()返回null,则必须关闭套接字并退出循环。如果出现任何IOException,您还必须关闭套接字。

作为参考,您不应该扩展
线程
,除非您正在更改线程的工作方式。在像您这样的情况下,您只需要一个
run
方法来运行线程,实现
Runnable
并说
new-thread(new-TCPClientManager(clientSocket,clientID)).start()
为您提供相同的功能,但不暗示线程的工作方式不同。作为参考,您不应该扩展
线程
,除非您正在更改线程的工作方式。在像您这样的情况下,您只需要一个
run
方法来运行线程,实现
Runnable
并说
new-thread(new-TCPClientManager(clientSocket,clientID)).start()
提供相同的功能,但不暗示线程的工作方式不同。这是一个游戏服务器,但我不希望它们在输入无效命令时断开连接。如果某个命令等于null,我就停止它,那么我如何不断地检查是否有接收到该命令?@BleedObsidian:if
readLine
返回null,这意味着客户端已关闭其连接端。您将无法在该连接上获得更多命令。但是因为你没有退出循环,你只能一遍又一遍地忙于读取null。好的,我已经更新了上面的代码。但现在,如果有一个客户端已经连接,它将不会拾取另一个?@BleedObsidian使用Runnable启动一个新线程,而不是仅仅运行它。这是一个游戏服务器,但我不希望它们在输入无效命令时断开连接。如果某个命令等于null,我就停止它,那么我如何不断地检查是否有接收到该命令?@BleedObsidian:if
readLine
返回null,这意味着客户端已关闭其连接端。您将无法在该连接上获得更多命令。但是因为你没有退出循环,你只能一遍又一遍地忙于读取null。好的,我已经更新了上面的代码。但现在,如果已经连接了一个客户端,它将不会拾取另一个?@BleedObsidian使用Runnable启动一个新线程,而不仅仅是运行它。
    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);
            }
        }
    }
}
    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;
        }
    }
}