Java 从socket.getInputStream()读取时返回的二进制字符
输出实际上如图所示问题在于docker原始流。它将Java 从socket.getInputStream()读取时返回的二进制字符,java,sockets,docker,character-encoding,java-io,Java,Sockets,Docker,Character Encoding,Java Io,输出实际上如图所示问题在于docker原始流。它将stdoud和stderr多路复用到一个通道中。为此,在内容的每一位之前,它发送一个8位头 如果以下内容用于stdout,则第一位为1,2用于stderr,0用于stdin 第二、第三和第四位始终为零 最后4位是以big-endian表示的内容长度 要对此进行解码,请执行以下操作: 阅读标题 确定内容长度 阅读内容(注意,即使内容是针对stderr的,我们不想要它,我们仍然需要阅读它) 如果内容是实际内容,则将其添加到缓冲区 以下测试对您提供
stdoud
和stderr
多路复用到一个通道中。为此,在内容的每一位之前,它发送一个8位头
- 如果以下内容用于stdout,则第一位为1,2用于stderr,0用于stdin
- 第二、第三和第四位始终为零
- 最后4位是以big-endian表示的内容长度
May 27, 2017 3:46:14 PM com.examenginedashboard.codePG.
service.HttpHijack post
INFO: header: Content-Type: application/vnd.
docker.raw-stream
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Connection: Upgrade
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Upgrade: tcp
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Api-Version: 1.27
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Docker-Experimental: false
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Server: Docker/17.03.1-ce (linux)
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header:
Input Bytes ...... [B@6436a7db
Socket String .............. Socket[addr=/127.0.0.1,port=2375,
localport=60804]
Result ...............
请更好地格式化代码(缩进可以提高可读性)。在这种情况下很难,但请提供一个工作示例,或者至少告诉我们服务器在做什么。@ThijsSteel我已经编辑了这个问题,并试图解释我的场景。请看一看。这将是非常有帮助的。!!我不能退出,因为我看到了错误。我确实看到一些错误,当您写入内容长度时,您使用payload.length(),而应该是字节数组的长度(UTF-8具有可变长度)响应头中有什么?也许反应很快?更重要的是,为什么不使用
HttpURLConnection
?@ThijsSteel感谢您的回复。。预期的输出是:您的话在这里!!你的话就在这里!!你的话就在这里!!来吧,喜欢它!!但是,如果您在第一行结果中看到上面的链接[此处的最终输出]…[某些二进制字符]在那里,我不明白为什么会出现此二进制字符。是否存在任何编码错误。再次感谢。您太棒了!!非常感谢,它就像一个符咒!!我已经工作了8天多了。我不明白整件事。有什么参考文件可以让我了解整个过程吗?。可能是我有点野心勃勃,我试着运行另一种编程语言,它有下面的序列它不工作它有下面的序列。。。。。[2、0、0、0、0、60、98、97、115、104、58、32、108、105、110、101、32、48、58、32、99、100、58、32、109、121、100、111、99、107、101、114、98、117、105、108、100、47、58、32、78111、32、115、117、99、104、32、102、105、108、101、32、111、114、32、114、100、114、114、101、101、99、116、111、111、116、111、111、111、111、114、10]我不理解行的内容大小=((标题[4]&0xFF)对于第一个问题:请注意,第一个字符是2,这意味着这是一条错误消息。如果您想解决第二个问题,也可以保存这些字符:我假设您知道整数存储为32位。一个字节是8位。我在该行中所做的是将所有字节合并为一个整数
package com.examenginedashboard.codePG.service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Map.Entry;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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();
System.out.println("Hostname ........."+host);
String path = uri.getPath();
System.out.println("Path..............."+path);
if (path.equals("")) {
path = "/";
}
String query = uri.getQuery();
System.out.println("Query................"+query);
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(StandardCharsets.UTF_8));
System.out.println("Input Bytes ...... "+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();
System.out.println("Socket String .............. "+socket.toString());
return socket.getInputStream();
}
public void close() throws java.io.IOException {
chin.close();
chout.close();
socket.close();
}}
May 27, 2017 3:46:14 PM com.examenginedashboard.codePG.
service.HttpHijack post
INFO: header: Content-Type: application/vnd.
docker.raw-stream
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Connection: Upgrade
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Upgrade: tcp
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Api-Version: 1.27
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Docker-Experimental: false
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header: Server: Docker/17.03.1-ce (linux)
May 27, 2017 3:46:14 PM com.examenginedashboard.
codePG.service.HttpHijack post
INFO: header:
Input Bytes ...... [B@6436a7db
Socket String .............. Socket[addr=/127.0.0.1,port=2375,
localport=60804]
Result ...............
public static void main(String[] args) throws FileNotFoundException, IOException {
byte[] data = new byte[] {1, 0, 0, 0, 0, 0, 0, 102, 89, 111, 117, 114, 32, 119, 111, 114, 100, 115, 32, 97, 114, 101, 32, 104, 101, 114, 101, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 32, 33, 33, 10, 89, 111, 117, 114, 32, 119, 111, 114, 100, 115, 32, 97, 114, 101, 32, 104, 101, 114, 101, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 32, 33, 33, 10, 89, 111, 117, 114, 32, 119, 111, 114, 100, 115, 32, 97, 114, 101, 32, 104, 101, 114, 101, 46, 46, 46, 46, 46, 46, 46, 46, 46,46, 46, 32, 33, 33, 10, 1, 0, 0, 0, 0, 0, 0, 21, 105, 110, 112, 117, 116, 32, 105, 110, 32, 87, 111, 114, 100, 115, 32, 58, 32, 32, 84, 101, 110, 1, 0, 0, 0, 0, 0, 0, 1, 10, 1, 0, 0, 0, 0, 0, 0, 19, 67, 79, 77, 69, 32, 79, 78, 32, 76, 73, 75, 69, 32, 73, 84, 32, 33, 33, 10};
InputStream is = new ByteArrayInputStream(data); //I just created this for testing
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] header = new byte[8];
while(true){
if(!readFully(is, header, 8)) break;
int contentSize = ((header[4] & 0xFF) << 24) | ((header[5] & 0xFF) << 16)
| ((header[6] & 0xFF) << 8) | (header[7] & 0xFF);
boolean actualContent = header[0] == 1;
byte[] content = new byte[contentSize];
if(!readFully(is, content, contentSize))break;
if(actualContent)
baos.write(content, 0, contentSize);
else
System.err.println(new String(content));
}
System.out.println(baos.toString());
}
/**
* Read a given number of bytes from the stream and store them in the buffer.
*
* @param is
* The input stream to read from
* @param buffer
* The buffer to store it in
* @size size
* The number of bytes to read
*
* @return True if and only if all bytes were read.
*/
public static boolean readFully(InputStream is, byte[] buffer, int size) throws IOException{
int totalAmountRead = 0;
while(totalAmountRead < size){
int amountJustRead = is.read(buffer, totalAmountRead, size-totalAmountRead);
if(amountJustRead == -1)
return false;
totalAmountRead += amountJustRead;
}
return true;
}
Your words are here........... !!
Your words are here........... !!
Your words are here........... !!
input in Words : Ten
COME ON LIKE IT !!