代码之家  ›  专栏  ›  技术社区  ›  markovuksanovic

Java死锁问题

  •  2
  • markovuksanovic  · 技术社区  · 14 年前

    我正在使用java套接字进行通信。在客户端,我进行了一些处理,此时我向cient发送了一个对象。代码如下:

    while (true) {
      try {
        Socket server = new Socket("localhost", 3000);
        OutputStream os = server.getOutputStream();
        InputStream is = server.getInputStream();
    
        CommMessage commMessage = new CommMessageImpl();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(commMessage);
        os.write(bos.toByteArray());
        os.flush();
    
        byte[] buff = new byte[512];
        int bytesRead = 0;
        ByteArrayOutputStream receivedObject = new ByteArrayOutputStream();
        while ((bytesRead = is.read(buff)) > -1) {
          receivedObject.write(buff, 0, bytesRead);
          System.out.println(receivedObject);
        }
        os.close();
        Thread.sleep(10000);
      } catch (IOException e) {
      } catch (InterruptedException e) {
      }
    }
    

    public void startServer() {
      Socket client = null;
      try {
        server = new ServerSocket(3000);
        logger.log(Level.INFO, "Waiting for connections.");
        client = server.accept();
        logger.log(Level.INFO, "Accepted a connection from: " + client.getInetAddress());
        os = new ObjectOutputStream(client.getOutputStream());
        is = new ObjectInputStream(client.getInputStream());
    
        // Read contents of the stream and store it into a byte array.
        byte[] buff = new byte[512];
        int bytesRead = 0;
        ByteArrayOutputStream receivedObject = new ByteArrayOutputStream();
        while ((bytesRead = is.read(buff)) > -1) {
          receivedObject.write(buff, 0, bytesRead);
        }
    
        // Check if received stream is CommMessage or not contents.
        CommMessage commMessage = getCommMessage(receivedObject);
        if (commMessage != null) {
          commMessage.setSessionState(this.sessionManager.getState().getState());
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(bos);
          oos.writeObject(commMessage);
          os.write(bos.toByteArray());
          System.out.println(commMessage.getCommMessageType());
        } else {
          processData(receivedObject, this.sessionManager);
        }
        os.flush();
        } catch (IOException e) {
        } finally {
          try {
            is.close();
            os.close();
            client.close();
            server.close();
          } catch (IOException e) {
        }
      }
    }
    

    如果我不尝试在客户端读取数据(如果我排除与读取相关的代码),那么上面的代码可以正常工作。但是如果我有那个代码,出于某种原因,我在访问输入流时会遇到某种死锁。你知道我做错了什么吗?提前谢谢。

    1 回复  |  直到 14 年前
        1
  •  5
  •   finnw    14 年前

    客户机和服务器都试图读取整个输入流(即,所有内容都达到EOF),但都没有发送EOF(通过调用 shutdownOutput() 在插座上。)

    为什么需要将对象数据临时存储在 ByteArrayOutputStream ? 如果您直接从socket输入流读取,这可能更容易修复。