Java 新ObjectInputStream导致挂起/超时
我知道这个问题已经被问过好几次了。然而,在所有其他问题上遵循建议之后,我仍然无法确定问题可能是什么 我有一个服务器和一个客户端。一个简单的乒乓球节目。在运行服务器和客户端并给它一些时间来运行它的进程之后,超时异常开始时不时地抛出 超时是为了防止阻塞,但是,如果删除,它将导致程序暂停 有没有办法防止这种情况发生 Server.javaJava 新ObjectInputStream导致挂起/超时,java,Java,我知道这个问题已经被问过好几次了。然而,在所有其他问题上遵循建议之后,我仍然无法确定问题可能是什么 我有一个服务器和一个客户端。一个简单的乒乓球节目。在运行服务器和客户端并给它一些时间来运行它的进程之后,超时异常开始时不时地抛出 超时是为了防止阻塞,但是,如果删除,它将导致程序暂停 有没有办法防止这种情况发生 Server.java public static void main(String args[]) { try { ServerSocket se
public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(3000);
while (true) {
Socket socket = serverSocket.accept();
String message = null;
try {
socket.setSoTimeout(3000);
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
message = (String) objectInputStream.readObject();
System.out.println("Server received " + message);
}
socket.close();
} catch (IOException | ClassNotFoundException ex) {
//This exception is thrown because it hangs, but why does it hang?
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if ((message != null) && (message.equals("Ping"))) {
try {
Socket pongSocket = new Socket("localhost", 3000);
pongSocket.setSoTimeout(3000);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(pongSocket.getOutputStream())) {
objectOutputStream.writeObject("Pong");
objectOutputStream.flush();
System.out.println("Server sent Pong");
}
pongSocket.close();
continue;
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
while (true) {
try {
Socket pingSocket = new Socket("localhost", 3000);
pingSocket.setSoTimeout(3000);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(pingSocket.getOutputStream())) {
objectOutputStream.writeObject("Ping");
System.out.println("Client sent Ping");
objectOutputStream.flush();
}
pingSocket.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(3000);
while (true) {
Socket socket = serverSocket.accept();
socket.setSoTimeout(250);
String message = null;
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
try {
message = (String) objectInputStream.readObject();
System.out.println("server read: " + message);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if ((message != null) && (message.equals("Ping"))) {
try {
objectOutputStream.writeObject("Pong");
System.out.println("server sent pong");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
objectInputStream.close();
objectOutputStream.close();
socket.close();
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
while (true) {
try {
Socket socket = new Socket("localhost", 3000);
String message;
socket.setSoTimeout(250);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject("Ping");
System.out.println("client sent ping");
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
message = (String) objectInputStream.readObject();
System.out.println("client read: " + message);
}
objectOutputStream.close();
socket.close();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Client.java
public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(3000);
while (true) {
Socket socket = serverSocket.accept();
String message = null;
try {
socket.setSoTimeout(3000);
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
message = (String) objectInputStream.readObject();
System.out.println("Server received " + message);
}
socket.close();
} catch (IOException | ClassNotFoundException ex) {
//This exception is thrown because it hangs, but why does it hang?
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if ((message != null) && (message.equals("Ping"))) {
try {
Socket pongSocket = new Socket("localhost", 3000);
pongSocket.setSoTimeout(3000);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(pongSocket.getOutputStream())) {
objectOutputStream.writeObject("Pong");
objectOutputStream.flush();
System.out.println("Server sent Pong");
}
pongSocket.close();
continue;
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
while (true) {
try {
Socket pingSocket = new Socket("localhost", 3000);
pingSocket.setSoTimeout(3000);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(pingSocket.getOutputStream())) {
objectOutputStream.writeObject("Ping");
System.out.println("Client sent Ping");
objectOutputStream.flush();
}
pingSocket.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(3000);
while (true) {
Socket socket = serverSocket.accept();
socket.setSoTimeout(250);
String message = null;
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
try {
message = (String) objectInputStream.readObject();
System.out.println("server read: " + message);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if ((message != null) && (message.equals("Ping"))) {
try {
objectOutputStream.writeObject("Pong");
System.out.println("server sent pong");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
objectInputStream.close();
objectOutputStream.close();
socket.close();
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
while (true) {
try {
Socket socket = new Socket("localhost", 3000);
String message;
socket.setSoTimeout(250);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject("Ping");
System.out.println("client sent ping");
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
message = (String) objectInputStream.readObject();
System.out.println("client read: " + message);
}
objectOutputStream.close();
socket.close();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
您没有任何东西可以限制发件人的速度。乍一看,我想说,您发送请求的速度比处理请求的速度快,这简直让服务器应接不暇。您在套接字上侦听的“服务器”无法与非限制的“客户端”竞争。您对服务器和客户端如何使用套接字感到困惑。你可能会在stackoverflow上找到很多例子,甚至可以通过Google找到更多的例子,但一般的习惯用法是:
server:
create server socket
call accept on server socket
with accepted socket
read request from socket
write response to socket
close accepted socket
loop back to accept
client:
create socket
call connect on socket
write request to socket
read response from socket
close socket
(Java会自动为您执行其中一些操作,例如,在创建套接字并指定主机和端口时,套接字类会为您调用connect。)
在您的服务器中,您在读取请求后关闭接受的套接字,然后创建并连接到新的套接字以发送响应,该响应将发送到localhost:3000(您的服务器)上侦听的任何对象。此外,在客户机中,您正在编写请求,但没有读取响应,而且是在一个紧密的循环中进行的,因此您正在创建大量到服务器的连接,这将快速填充accept积压
实际上,生产应用程序会在服务器中使用线程,甚至使用更高级别的库,甚至像Tomcat这样的整个服务器,但在底层,它们基本上都在做上述工作,所以理解这一点很好
为了演示,您的代码应该是这样的:
Server.java
public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(3000);
while (true) {
Socket socket = serverSocket.accept();
String message = null;
try {
socket.setSoTimeout(3000);
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
message = (String) objectInputStream.readObject();
System.out.println("Server received " + message);
}
socket.close();
} catch (IOException | ClassNotFoundException ex) {
//This exception is thrown because it hangs, but why does it hang?
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if ((message != null) && (message.equals("Ping"))) {
try {
Socket pongSocket = new Socket("localhost", 3000);
pongSocket.setSoTimeout(3000);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(pongSocket.getOutputStream())) {
objectOutputStream.writeObject("Pong");
objectOutputStream.flush();
System.out.println("Server sent Pong");
}
pongSocket.close();
continue;
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
while (true) {
try {
Socket pingSocket = new Socket("localhost", 3000);
pingSocket.setSoTimeout(3000);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(pingSocket.getOutputStream())) {
objectOutputStream.writeObject("Ping");
System.out.println("Client sent Ping");
objectOutputStream.flush();
}
pingSocket.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(3000);
while (true) {
Socket socket = serverSocket.accept();
socket.setSoTimeout(250);
String message = null;
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
try {
message = (String) objectInputStream.readObject();
System.out.println("server read: " + message);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if ((message != null) && (message.equals("Ping"))) {
try {
objectOutputStream.writeObject("Pong");
System.out.println("server sent pong");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
objectInputStream.close();
objectOutputStream.close();
socket.close();
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
while (true) {
try {
Socket socket = new Socket("localhost", 3000);
String message;
socket.setSoTimeout(250);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject("Ping");
System.out.println("client sent ping");
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
message = (String) objectInputStream.readObject();
System.out.println("client read: " + message);
}
objectOutputStream.close();
socket.close();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Client.java
public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(3000);
while (true) {
Socket socket = serverSocket.accept();
String message = null;
try {
socket.setSoTimeout(3000);
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
message = (String) objectInputStream.readObject();
System.out.println("Server received " + message);
}
socket.close();
} catch (IOException | ClassNotFoundException ex) {
//This exception is thrown because it hangs, but why does it hang?
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if ((message != null) && (message.equals("Ping"))) {
try {
Socket pongSocket = new Socket("localhost", 3000);
pongSocket.setSoTimeout(3000);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(pongSocket.getOutputStream())) {
objectOutputStream.writeObject("Pong");
objectOutputStream.flush();
System.out.println("Server sent Pong");
}
pongSocket.close();
continue;
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
while (true) {
try {
Socket pingSocket = new Socket("localhost", 3000);
pingSocket.setSoTimeout(3000);
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(pingSocket.getOutputStream())) {
objectOutputStream.writeObject("Ping");
System.out.println("Client sent Ping");
objectOutputStream.flush();
}
pingSocket.close();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]) {
try {
ServerSocket serverSocket = new ServerSocket(3000);
while (true) {
Socket socket = serverSocket.accept();
socket.setSoTimeout(250);
String message = null;
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
try {
message = (String) objectInputStream.readObject();
System.out.println("server read: " + message);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
if ((message != null) && (message.equals("Ping"))) {
try {
objectOutputStream.writeObject("Pong");
System.out.println("server sent pong");
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
objectInputStream.close();
objectOutputStream.close();
socket.close();
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
while (true) {
try {
Socket socket = new Socket("localhost", 3000);
String message;
socket.setSoTimeout(250);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject("Ping");
System.out.println("client sent ping");
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
message = (String) objectInputStream.readObject();
System.out.println("client read: " + message);
}
objectOutputStream.close();
socket.close();
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
除了flush()和swift部分,请看以下问题:。我更喜欢在serverSocket.accept()调用创建新套接字后创建一个线程来处理IO。创建一个线程并传递客户端套接字,然后在那里执行IO。那么解决方案是什么呢?它不仅仅是一个简单的修复程序,您需要修改代码以使其像上面那样工作。例如,在Server.java中,读取请求后,不要立即关闭套接字,然后打开一个新的套接字。相反,请检查请求,然后发送相应的响应,然后关闭套接字并循环回accept。@ravindra感谢您做了我用“您可能会找到一堆示例”进行的研究我确实在这里搜索过,但我在搜索中指定了Java,您所指的答案是关于Swift的一个问题,尽管答案是一个很好的一般性答案,所以值得一看。