当前位置: 首页 > 知识库问答 >
问题:

Java套接字和ServerSocket通信死锁

公孙和怡
2023-03-14

我试图建立一个多人游戏与游戏服务器运行最多4个客户端,使用java套接字和ServerSocket。在此代码中,我将客户端的数量限制在1个,并对播放器和服务器使用阻塞I/O模型。

游戏服务器线程(实现Runnable)使用套接字输入流从每个客户端接收“Snake object to Snake[i]”和“char变量to DirInput”,并使用套接字输出流发送“Snake object Array Snake”和“Apple object Apple”。Snake对象和Apple对象都是可序列化的。

public void run()
{
    while(true)
    {
        //playerCount is fixed to 1 for testing
        for(int i=0; i<playerCount; i++)
        {
            try {
                //get every snake object from each player
                ObjectInputStream objectInputStream = new ObjectInputStream(clientSocket[i].getInputStream());
                snake[i] = (Snake)objectInputStream.readObject();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        for(int i=0; i<playerCount; i++)
        {
            try {
                Reader charInputStream = new InputStreamReader(clientSocket[i].getInputStream());
                dirInput = (char) charInputStream.read();

                //DO SOMETHING WITHOUT COMMUNICATION

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        for(int i=0; i<playerCount; i++)
        {
            try {
                OutputStream outputStream = clientSocket[i].getOutputStream();
                outputStream.write(i);

                ObjectOutputStream objectOutputStream = new ObjectOutputStream(clientSocket[i].getOutputStream());
                objectOutputStream.writeObject(snake);
                objectOutputStream.writeObject(apple);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

每个播放器客户端线程(实现Runnable)向服务器发送“Snake object MySnake”和“Char变量InputControl”,并从服务器接收“int变量to PlayerNumber”、“Snake object Array to Board.Snakes”和“Apple object to Board.Apple”。

public void run() {
    while(true)
    {
        try {
            Thread.sleep(50);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(gameSocket.getOutputStream());
            objectOutputStream.writeObject(mySnake);

            Writer charOutputWriter = new OutputStreamWriter(gameSocket.getOutputStream());
            charOutputWriter.write(inputControl);

            playerNumber = gameSocket.getInputStream().read();

            ObjectInputStream objectInputStream = new ObjectInputStream(gameSocket.getInputStream());
            board.snakes = (Snake[])objectInputStream.readObject();
            board.apple = (Apple)objectInputStream.readObject();
            mySnake = board.snakes[playerNumber];

            board.repaint();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

问题是,当我同时启动游戏服务器和客户端并试图通信时,游戏服务器线程和玩家客户端线程在通信时都停止了。

当我调试时,游戏服务器线程被从客户端线程读取char输入(dirInput)所困,而客户端线程被从游戏服务器线程读取int输入(playerNumber)所困。看到两个线程都被InputStream卡住了,我认为死锁是在使用InputStream时发生的,因为两个线程都试图使用InputStream。但我不确定僵局是否真的发生了。

共有1个答案

柳英资
2023-03-14

我不知道你到底做了什么!但问题是您多次创建ObjectInputStream!如果您想知道问题出在哪里,只需创建一个扩展java.io.InputStream类的简单类,并通过将该类作为基本InputStream来创建一个ObjectInputStream。您将看到,当ObjectInputStream类创建时,它将尝试读取4个字节作为头字节!所以这意味着你丢失了一些数据,这就是为什么你的线程卡住的原因!如果有反编译程序,也可以检查ObjectInputStream的代码。

 类似资料:
  • 我想找个人来澄清一个我相信我有的误解。我在读Java上的套接字编程,并不真正理解事情的实际流程是什么。以下是我对以下场景的两种可能的解释。 创建套接字实例 null 服务器接受客户端之后的连接会是这样的吗?(客户端与服务器创建的套接字通信,而不是与服务器套接字通信) 或者图表会像这样吗?(客户端通过ServerSocket与服务器保持通信。服务器通过接受连接时创建的套接字进行通信。)

  • 我目前有一个简单的即时消息程序,它利用Java的Socket和ServerSocket类。它按预期运行,但当我尝试关闭连接时,它没有使用4路握手TCP断开来关闭连接。相反,它使用RST数据包突然关闭连接。 关闭连接的方法是从客户端向服务器发送一个字符串,服务器将把它识别为关闭连接的命令。然后,我在服务器上使用方法,在客户端上使用方法。 使用这些类正确关闭TCP连接的正确方式和/或事件顺序是什么?

  • 问题内容: 我试图用没有gui的服务器连接带有gui的客户端。连接已完成,但我看不到这两个应用程序之间的任何消息。(我应该在客户端中找到SERVER HERE,在服务器中找到CLIENT HERE) 客户端连接代码: (输入和输出在此客户端类扩展到的GUI类中定义。定义为“受保护的BufferedReader输入;受保护的PrintWriter输出;”) 另外,服务器代码: 连接似乎还可以,所以我

  • 问题内容: 我的应用程序中需要进行两个过程(Java和Python)进行通信。我注意到套接字通信占用了93%的运行时间。为什么沟通这么慢?我应该寻找套接字通信的替代方法还是可以使其更快? 更新:我发现了一个简单的修复程序。似乎由于某些未知原因,缓冲输出流并未真正被缓冲。因此,现在我将所有数据放入两个客户端/服务器进程的字符串缓冲区中。我用flush方法将其写入套接字。 我仍然对使用共享内存在进程之

  • 我正在尝试连接一个带有gui的客户端和一个没有gui的服务器。连接正在进行中,但我看不到这两个应用程序之间的任何消息。(我应该将服务器放在客户端中,而将客户端放在服务器中) 客户端连接代码: PS:我也在服务器中尝试了PrintWriter,也尝试了try catch in stream语句,问题仍然存在。

  • 问题内容: 我喜欢NodeJS的某些功能,特别是JQuerification,通过socket.io的websocket兼容性,我不能与JSP一起使用的视图和CSS引擎(当然还有异步调用)。至少据我所知。因此,我计划在后端为Java的情况下创建应用程序,前端由NodeJS生成。前端表单将数据发送到NodeJS,后者将通过NodeJS和Java后端之间的套接字连接将其传递到Java后端。因此,Nod