我正在使用 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) {
}
}
}
如果我不尝试在客户端读取数据,上面的代码就可以正常工作(如果我排除与读取相关的代码)。但是如果我有那个代码,出于某种原因,我在访问输入流时会遇到某种死锁。任何想法我可能做错了什么?提前致谢。
最佳答案
客户端和服务器都试图读取整个输入流(即直到 EOF 的所有内容)但都没有发送 EOF(通过在套接字上调用 shutdownOutput()
。)
为什么需要将对象数据临时存储在ByteArrayOutputStream
中?如果您直接从套接字输入流中读取,这可能更容易修复。
关于Java死锁问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2797087/