2010-05-09 235 views
2

我正在使用java套接字进行通信。在客户端我有一些处理,在这一点上,我发送一个对象给cient。的代码如下:Java死锁问题

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) { 
    } 
    } 
} 

上面的代码作品好吧,如果我不尝试读取客户端的数据(如果我排除与阅读相关的代码)。但是如果我有这些代码,出于某种原因,在访问输入流时会遇到某种死锁。任何想法我可能做错了什么?提前致谢。

回答

5

客户端和服务器正在试图读取整个输入流(即一切都交给EOF)但也不是发送EOF(通过插座上调用shutdownOutput()。)

为什么你需要存储的对象数据暂时在ByteArrayOutputStream?如果直接从套接字输入流中读取,这可能会更容易解决。

+0

谢谢,我会在今天晚些时候尝试解决方案......但是我使用ByteArrayOutputStream的原因是因为我不知道客户端会发生什么 - 流可以包含两种类型的对象之一。所以我所做的是我完全读取流并尝试转换为一个对象 - 如果失败,它只能是其他对象(或错误:))。你认为我应该采取其他方式吗? – markovuksanovic 2010-05-09 10:04:47

+0

只需将它读入一个Object并使用instanceof即可。我看不出你在做什么增加了什么,你仍然必须这样做。 – EJP 2010-05-09 10:09:18

+0

你说得对。我应该做一些重构。感谢您指出了这一点。 – markovuksanovic 2010-05-09 10:18:10