首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ServerSocket与ServerSocket通信死锁

ServerSocket与ServerSocket通信死锁
EN

Stack Overflow用户
提问于 2019-05-07 00:09:24
回答 1查看 191关注 0票数 0

我试图构建一个多人游戏,游戏服务器最多与4个客户端一起操作,使用java套接字和ServerSocket。在此代码中,我将客户端限制为1,用于测试,并对播放器和服务器使用阻塞I/O模型。

游戏服务器线程(实现可运行)使用套接字输入流从每个客户端接收'Snake对象到snakei‘和'char变量到dirInput’,并使用socket输出流发送'Snake object Array snake‘和'Apple apple。Snake对象和Apple对象都是可序列化的。

在这里,clientSocket数组包含所有连接的客户端套接字,而这些套接字直到播放器结束连接才关闭(这意味着每个播放器的整个游戏都用一个套接字完成)。对象扩展了游戏图形的JComponent (显示游戏游戏)。

代码语言:javascript
复制
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();
            }
        }
    }
}

每个inputControl‘播放器客户端线程(实现可运行)向服务器发送'Snake object mySnake’和'char变量‘,并从服务器接收'int变量到playerNumber','Snake object和从服务器接收'Apple到board.apple’‘。

代码语言:javascript
复制
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();
        }
    }
}

问题是,当我同时启动游戏服务器和客户端并尝试进行通信时,游戏服务器线程和Player客户端线程在通信时都会出现问题。

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

如何使两个线程进行通信?游戏服务器线程和播放器客户端线程都应该使用非阻塞I/O模型吗?

EN

回答 1

Stack Overflow用户

发布于 2019-05-13 00:49:44

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56013864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档