如何处理 ObjectOutputStream
和 ObjectInputStream
以便 Server
实例正确记录接收到的 Object
。目前,它永远不会走得那么远。每次客户端运行时,服务器都会“等待数据”,但似乎从未真正收到数据。
服务器:
package net.bounceme.dur.driver;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server {
private static final Logger log = Logger.getLogger(Server.class.getName());
private final RecordQueue recordsQueue = new RecordQueue();
public static void main(String[] args) {
Properties props = PropertiesReader.getProps();
int portNumber = Integer.parseInt(props.getProperty("port"));
while (true) {
try {
new Server().inOut(portNumber);
} catch (java.net.SocketException se) {
Logger.getLogger(Server.class.getName()).log(Level.FINE, "spammy", se);
} catch (IOException ioe) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ioe);
} catch (ClassNotFoundException cnf) {
Logger.getLogger(Server.class.getName()).log(Level.INFO, null, cnf);
}
}
}
public void inOut(int portNumber) throws IOException, ClassNotFoundException {
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket socket = serverSocket.accept();
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
log.info("...connected...waiting for data...");
MyRecord recordFromClient = (MyRecord) objectInputStream.readObject();
objectOutputStream.writeObject(recordFromClient);
objectOutputStream.flush();
objectInputStream.close();
objectOutputStream.close();
log.info(recordFromClient.toString());//never logs
System.out.println("never gets here");
}
}
每次客户端运行时,服务器都会等待数据,但至少根据下面的输出,永远不会收到数据。
thufir@dur:~$
thufir@dur:~$ java -jar NetBeansProjects/Server/dist/Server.jar
Jun 29, 2014 9:28:45 PM net.bounceme.dur.driver.Server inOut
INFO: ...connected...waiting for data...
Jun 29, 2014 9:28:46 PM net.bounceme.dur.driver.Server inOut
INFO: ...connected...waiting for data...
客户端代码:
package net.bounceme.dur.driver;
import java.net.*;
import java.io.*;
import java.util.Properties;
import java.util.logging.Logger;
public class Client {
private static final Logger log = Logger.getLogger(Client.class.getName());
public void put(String server, int portNumber, Socket socket, ObjectOutputStream objectOutputStream) throws IOException, ClassNotFoundException {
socket = new Socket(server, portNumber);
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
MyRecord record = new MyRecord(1, "foo");
objectOutputStream.writeObject(record);
objectOutputStream.flush();
objectOutputStream.close();
}
public static void main(String args[]) throws IOException, ClassNotFoundException {
Properties props = PropertiesReader.getProps();
int portNumber = Integer.parseInt(props.getProperty("port"));
String server = (props.getProperty("server"));
Socket socket = null;
ObjectOutputStream objectOutputStream = null;
ObjectInputStream objectInputStream = null;
new Client().put(server, portNumber, socket, objectOutputStream);
}
}
最佳答案
客户端和服务器不仅必须在如何发送数据方面达成一致,而且还必须在何时关闭套接字方面达成一致。单方面关闭套接字将关闭连接并阻止接收甚至已经发送的数据。我认为这就是这里发生的事情。
客户端代码:
objectOutputStream.writeObject(record);
objectOutputStream.flush();
objectOutputStream.close();
这是不间断执行的,因此一旦在线上发送了最后一个字节,套接字就会关闭。因此,服务器的回复无法发送。
服务器代码:
MyRecord recordFromClient = (MyRecord) objectInputStream.readObject();
objectOutputStream.writeObject(recordFromClient);
显然,接收发生得比发送晚一点,因此服务器会阻塞。
保持套接字从双方打开,直到客户端收到;然后他可以关闭套接字。当尝试再次读取时,服务器应该看到文件结尾,并可以相应地关闭。 (当然,更复杂的握手是可能的。)
稍后
为了证实这一点,只需添加 Thread.sleep(2000);在客户端的刷新和关闭之间 - 服务器确实会“到达这里”。
关于java - 为什么服务器没有收到客户端发送的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24482968/