我正在尝试打开一个连接并保持打开,直到我决定关闭它。
它适用于第一个sendStdinToConsole
,但当我再次调用该函数时,我得到:
java.net.SocketException:套接字关闭后无法发送:套接字写入错误
我从不打电话给close()。为什么要关闭?
基本上,当我点击连接按钮时,我只想execConsole
一次。每次我点击另一个按钮,它都会向WebSocket发送一个输入,直到我断开它为止。
private HttpHijack ws = null;
public HttpHijack execConsole(String containerName, String command, String user) {
Settings settings = Settings.getSettings();
DockerClient dockerClient = dockerClient();
Container container = getContainer(containerName);
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()).withAttachStdout(true).withAttachStdin(true).withTty(false).withAttachStderr(true).withCmd(command).withUser(user).exec();
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
try {
ws = new HttpHijack(new URI("http://" + settings.getDockerIP() + ":" + settings.getDockerPort() + "/exec/" + execCreateCmdResponse.getId() + "/start"));
} catch (URISyntaxException e) {
e.printStackTrace();
}
String payload = "{\"Detach\": false,\"Tty\": true}";
try {
ws.post(headers, payload);
} catch (IOException e) {
e.printStackTrace();
}
return ws;
}
public String sendStdinToConsole(String stdin) {
InputStream input = null;
try {
input = ws.send(stdin);
} catch (IOException e) {
e.printStackTrace();
}
String response = null;
try {
response = IOUtils.readLines(input).toString();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(response);
return response;
}
HIJACK CLASS
public class HttpHijack {
private static final Logger log = LoggerFactory.getLogger(HttpHijack.class);
private URI uri;
private Socket socket;
private boolean handshakeCompleted;
private InputStream chin;
private OutputStream chout;
public HttpHijack(URI url) {
uri = url;
}
public void post(Map<String, String> headers, String payload) throws java.io.IOException {
String host = uri.getHost();
String path = uri.getPath();
if (path.equals("")) {
path = "/";
}
String query = uri.getQuery();
if (query != null) {
path = path + "?" + query;
}
socket = createSocket();
chout = socket.getOutputStream();
StringBuffer extraHeaders = new StringBuffer();
if (headers != null) {
for (Entry<String, String> entry : headers.entrySet()) {
extraHeaders.append(entry.getKey() + ": " + entry.getValue() + "\r\n");
}
}
StringBuffer request = new StringBuffer();
request.append("POST " + path + " HTTP/1.1\r\n");
request.append("Upgrade: tcp\r\n");
request.append("Connection: Upgrade\r\n");
request.append("Host: " + host + "\r\n");
if (headers != null) {
for (Entry<String, String> entry : headers.entrySet()) {
request.append(entry.getKey() + ": " + entry.getValue() + "\r\n");
}
}
request.append("Content-Length: " + payload.length() + "\r\n");
request.append("\r\n");
request.append(payload);
chout.write(request.toString().getBytes());
chout.flush();
chin = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(chin));
String header = reader.readLine();
if (!header.equals("HTTP/1.1 101 UPGRADED")) {
throw new IOException("Invalid handshake response: " + header);
}
do {
header = reader.readLine();
log.info("header: {}", header);
} while (!header.equals(""));
handshakeCompleted = true;
}
private Socket createSocket() throws java.io.IOException {
String scheme = uri.getScheme();
String host = uri.getHost();
int port = uri.getPort();
if (port == -1) {
if (scheme.equals("https")) {
port = 443;
} else if (scheme.equals("http")) {
port = 80;
} else {
throw new IllegalArgumentException("Unsupported scheme");
}
}
if (scheme.equals("https")) {
SocketFactory factory = SSLSocketFactory.getDefault();
return factory.createSocket(host, port);
} else {
return new Socket(host, port);
}
}
public InputStream send(String command) throws java.io.IOException {
if (!handshakeCompleted) {
throw new IllegalStateException("Handshake not complete");
}
chout.write(command.getBytes("UTF-8"));
chout.flush();
// looks like "exit" can't explicitly close the session,
// shutdown output stream to force close it
// so that stdout/stderr can be consumed via inputstream
socket.shutdownOutput();
return socket.getInputStream();
}
public void close() throws java.io.IOException {
chin.close();
chout.close();
socket.close();
}
}
答案 0 :(得分:0)
您在socket.shutdownOutput
功能结束时执行了send()
。然后,您尝试再次发送sendStdinToConsole()
,但输出仍将关闭。或者在哪里再次启用输出?
答案 1 :(得分:0)
您尝试连接的终端设备未启用 telnet。