所以我正在用Java创建一个聊天服务器,以便在我的Minecraft服务器中依赖Hamachi进行托管和通信。它完美无缺,除了一件事:我无法弄清楚我的生活如何向服务器添加命令。我的主循环如下:
/*Executed in constructor*/
public void listen(int port) throws IOException {
//Initialize the ServerSocket
ss = new ServerSocket(port);
System.out.println("Listening on " + InetAddress.getLocalHost() + ":" + ss.getLocalPort());
running = true;
//Keep accepting connections
while (running) {
//Get the incoming connection
Socket s = ss.accept();
System.out.println("Connection from: " + getFullIP(s));
//Create a DataOutputStream for writing data to the other side
DataOutputStream dataOut = new DataOutputStream(s.getOutputStream());
//Save this stream so I don't have to make it again
outputStreams.put(s, dataOut);
//Create a new thread for this connection
new ServerThread(this, s);
if (!running) {
stop();
}
Scanner cmdScanner = new Scanner(System.in);
String command = cmdScanner.next();
processCommand(command);
}
}
此代码的结果是我无法在客户端连接到服务器之前键入命令(因为ss.accept()
)。在我执行命令之前,客户端无法连接(cmdScanner.next()
)。我该如何解决这个问题?
答案 0 :(得分:1)
我认为你的命令处理器应该在另一个线程中。恕我直言服务器应该始终有一个线程,只有作业是接收新连接并调度它。处理您的输入应该是其他线程的一部分。
public class TestThread
{
public static void main(String[] args)
{
new ConnectionDispatcher(8080).start();
new CommandProcessor().start();
}
}
class ConnectionDispatcher extends Thread{
private int port;
private OutputStream outputStreams;
ConnectionDispatcher(int port)
{
this.port = port;
}
@Override
public void run()
{
try
{
listen(port);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void listen(int port) throws IOException
{
//Initialize the ServerSocket
ss = new ServerSocket(port);
System.out.println("Listening on " + InetAddress.getLocalHost() + ":" + ss.getLocalPort());
boolean running = true;
//Keep accepting connections
while (running) {
//Get the incoming connection
Socket s = ss.accept();
System.out.println("Connection from: " + getFullIP(s));
//Create a DataOutputStream for writing data to the other side
DataOutputStream dataOut = new DataOutputStream(s.getOutputStream());
//Save this stream so I don't have to make it again
outputStreams.put(s, dataOut);
//Create a new thread for this connection
new ServerThread(this, s);
}
}
}
class CommandProcessor extends Thread{
@Override
public void run()
{
Scanner cmdScanner = new Scanner(System.in);
String command = cmdScanner.next();
processCommand(command);
}
}
答案 1 :(得分:1)
当我开始网络时,我遇到了同样的问题。您的线程在ss.accept()处停止,然后在代码中不继续。您需要实现专用于ServerSocket的另一个Thread。这是一个例子:
public class Server implements Runnable
{
ServerSocket server; // the serverSock your clients will connect to
Thread thread; // the thread for your server
boolean running; // whether or not the server is running
public Server(int port)
{
running = false; // server is not yet running
connect(port); // setup server
}
public void connect(int port)
{
try
{
server = new ServerSocket(port); setup server on port
running = true; // server is running
thread = new Thread(this); // initialize server thread
thread.start(); // start thread
} catch(Exception e){e.printStackTrace(); running = false;} // port is in use
}
public void disconnect()
{
try
{
server.close();
}catch(Exception e){e.printStackTrace();}
running = false;
thread = null;
server = null;
}
public void run()
{
while(running)
{
Socket client = server.accept(); // client connects to server
// handle the client...
ClientHandler handler = new ClientHandler(client);
}
}
public class ClientHandler implements Runnable
{
Thread clientThread;
DataOutputStream out;
public ClientHandler(Socket socket)
{
out = new DataOutputStream(socket.getOutputStream());//setup the output stream
clientThread = new Thread(this); // setup the new thread
clientThread.start(); // start the thread
}
public void run()
{
/* this is where you get your input from the console and then
* send the output to the client
*/
}
}
}
这应该让你的主线不会卡在server.accept()希望这有帮助!