1

太糟糕了,我不得不硬重启(按住电源按钮),它甚至没有给我调试的时间,所以如果我在这里没有得到答案,我基本上就完蛋了。我知道它是服务器端的(当我不运行客户端时会发生这种情况,但如果我这样做也会发生)。

这是服务器代码:

package cypri.games.cybatarserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class CybatarServer extends JFrame implements Runnable{
    String verNum = "0.0.0";
    JScrollPane jsp;
    JTextArea mainText;
    boolean stopServer = false;
    boolean waitForPlayers = true;
    Vector<Player> playersConnected;
    byte playerID = -1;

    public CybatarServer(){
        playersConnected = new Vector<Player>();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBounds(100, 100, 400, 100);

        this.setTitle("Cybatar Server " + verNum);

        mainText = new JTextArea(50, 10);
        mainText.setText("Welcome to CybatarServer "+ verNum + "!\n");
        mainText.setEditable(false);

        jsp = new JScrollPane(mainText);
        this.add(jsp);

        this.setVisible(true);
    }

    public static void main(String[] args){
        CybatarServer cyserv = new CybatarServer();
        cyserv.run();
    }

    @Override
    public void run() {

        try { 
            final ServerSocket serverSocket = new ServerSocket(44444);


            while(!stopServer){
                if(waitForPlayers){
                    new Thread(new Runnable() {
                        public void run() {

                            Socket clientSocket = null;
                                try {
                                    clientSocket = serverSocket.accept();
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                playerID++;
                                new PlayerThread(playerID, playersConnected, mainText, playerID, clientSocket).start();
                                mainText.append("Player " + playerID + " connected!");

                        }
                    }).start();
                }

                else{
                    for(int i = 0; i < playersConnected.size(); i++){
                        playersConnected.get(i).update();
                    }
                }

                Thread.yield();
            }
        } catch (Exception e) { e.printStackTrace(); }
    }
}

这里有什么东西会导致我的电脑完全死机吗?如果是这样,我该如何解决?

4

4 回答 4

11

我猜测

while(!stopServer){
   if(waitForPlayers){
       new Thread(new Runnable() {
         ....

正在生成和调用大量线程。这将在 CPU(运行这些线程)和内存(每个线程分配自己的堆栈空间)方面严重影响您的机器。

我怀疑你想接受传入的连接,然后才分配/启动一个线程。请注意,这仍然会让您面临 DOS 攻击(想象一下,如果有无限数量的玩家加入),但这对您来说可能不是一个实际问题。

于 2012-07-10T16:29:00.787 回答
3

旁注:在 UI 线程中运行 UI 内容

这部分:

while(!stopServer){
    if(waitForPlayers){
         new Thread(...).start();
     }
}

除非 stopServer 或 waitForPlayers 标志被快速更改,否则将创建大量线程。挂了也就不奇怪了...

于 2012-07-10T16:30:22.867 回答
2

看来您永远不会设置waitForPlayersfalse. 因此,每次while(!stopServer)循环时,都会产生一个新线程,从而冻结您的计算机。

于 2012-07-10T16:29:36.487 回答
1

显然没有尝试过运行它,但是这个结构让我觉得是一个潜在的分叉炸弹:

              new Thread(new Runnable() {
                    public void run() {
                            ...
                            new PlayerThread(playerID, playersConnected, mainText, playerID, clientSocket).start();
                            ...
              }
于 2012-07-10T16:29:57.657 回答