[英]java socket InputStream hangs/blocks on both client and server
I am recently working on a tiny program aimed to close the browser remotely.我最近正在开发一个旨在远程关闭浏览器的小程序。 The basic procedures are as follow:
基本程序如下:
Server side:服务器端:
Client side:客户端:
Code below:下面的代码:
Server.java服务器.java
package socket;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
private static ExecutorService es = Executors.newFixedThreadPool(5);
public static void main(String[] args) throws IOException {
InetAddress targetAddress = null;
NetworkInterface ni = NetworkInterface.getByName("eth2");
System.out.println(ni);
Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
while(inetAddresses.hasMoreElements()) {
InetAddress inetAddress = inetAddresses.nextElement();
if(inetAddress.toString().startsWith("/10")) {
targetAddress = inetAddress;
break;
}
}
ServerSocket sSocket = new ServerSocket(11111, 0, targetAddress);
while(true) {
System.out.println("Server is running...");
Socket client = sSocket.accept();
System.out.println("Client at: " + client.getRemoteSocketAddress());
es.execute(new ClientRequest(client));
}
}
}
ClientRequest.java客户端请求.java
package socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientRequest implements Runnable {
private Socket client;
public ClientRequest(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
System.out.println("Handled by: " + Thread.currentThread().getName());
// get input/output streams for client socket
InputStream cis = client.getInputStream();
OutputStream cos = client.getOutputStream();
// buffer size : 1024 ?
byte[] buffer = new byte[1024];
int recvSize;
int totalRecvSize = 0;
while(-1 != (recvSize = cis.read(buffer, totalRecvSize, 1024 - totalRecvSize))) {
totalRecvSize += recvSize;
}
String command = new String(buffer, "utf-8");
System.out.println("Command from client: " + command);
String commandNative = CommandMap.getNativeCommand(command.trim());
if(null != commandNative) {
Process np = Runtime.getRuntime().exec(commandNative);
InputStream is = np.getInputStream();
byte[] bufferProcess = new byte[1024];
int bytesRead;
int totalBytesRead = 0;
while(-1 != (bytesRead = is.read(bufferProcess, totalBytesRead, 1024 - totalBytesRead))) {
totalBytesRead += bytesRead;
}
// give feed back of process output
cos.write(bufferProcess);
// close process input stream
is.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null != client) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
and finally, Client.java最后, Client.java
package socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
public class Client {
private static final int BUF_SIZE = 1024;
// feedback message size will not exceed 1024 bytes
private static final byte[] BUFFER = new byte[BUF_SIZE];
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
Socket socket = new Socket("10.117.37.176", 11111);
System.out.println("Connected to Server...");
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
String command = "kill ie";
byte[] commandBytes = command.getBytes(Charset.forName("utf-8"));
System.out.println("Send: " + command);
os.write(commandBytes);
System.out.println("After send: " + command);
int totalRecv = 0;
int recvSize;
while(-1 != (recvSize = is.read(BUFFER, totalRecv, BUF_SIZE - totalRecv))) {
totalRecv += recvSize;
}
String feedback = new String(BUFFER, "utf-8");
System.out.println("Feedback: " + feedback);
socket.close();
}
}
To reiterate the problems:重申问题:
I am wondering what's the hidden causes in this code?我想知道这段代码中隐藏的原因是什么?
Your socket reading code is reading until EOF.您的套接字读取代码正在读取直到 EOF。 you will not receive EOF until you close the socket.
在关闭套接字之前,您不会收到 EOF。 hence, your code never proceeds.
因此,您的代码永远不会继续。
if you only want to send a single command on the socket connection, then close the OutputStream after writing the command (using Socket.shutdownOutput()
).如果您只想在套接字连接上发送单个命令,则在编写命令后关闭 OutputStream(使用
Socket.shutdownOutput()
)。
If you want to send multiple commands on a single socket connection, then you will need to come up with a way of delimiting each command ( simple example here ).如果您想在单个套接字连接上发送多个命令,那么您需要想出一种分隔每个命令的方法(此处为简单示例)。
You are reading until EOS at both ends, which is a poor choice, as you can't 'send' the EOS without losing the ability to send further data on the same connection.您正在阅读直到两端的 EOS,这是一个糟糕的选择,因为您无法“发送” EOS 而不会失去在同一连接上发送更多数据的能力。 You need to redesign your application protocol so you can read a command at a time without requiring that the connection be closed to complete it.
你需要重新设计你的应用程序协议,这样你就可以一次读取一个命令,而不需要关闭连接来完成它。 For example, send lines, or a length word prefix, or a self-describing protocol such as XML or Java Object Serialization, or whatever you can read via DataInputStream without relying on EOFException.
例如,发送行,或长度字前缀,或诸如 XML 或 Java 对象序列化之类的自描述协议,或者您可以通过 DataInputStream 读取的任何内容,而无需依赖 EOFException。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.