- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在运行一个多线程的简约 http(s) 服务器(虽然不是 Web 服务器),它接受三个服务器套接字上的连接:本地、互联网和互联网-ssl。
每个套接字都有 1000 毫秒的 so 超时(将来可能会降低)。
工作线程读取这样的请求:
byte[] reqBuffer = new byte[512];
theSocket.getInputStream().read(reqBuffer);
现在的问题是,新实现的 ssl 套接字会出现 1/n-1 记录拆分技术的问题。还有一些客户端在使用 ssl(4/n-4 等)时以其他奇怪的方式拆分,所以我想我可能只是像这样执行多次读取:
byte[] reqBuffer = new byte[512];
InputStream is = theSocket.getInputStream();
int read = is.read(reqBuffer, 0, 128); // inital read - with x/n-x this is very small
int pos = 0;
if (read > 0) {
pos = read;
}
int i = 0;
do {
read = is.read(reqBuffer, pos, 128);
if (read > 0) {
pos += read;
}
i++;
} while(read == 128 && i < 3); // max. 3 more reads (4 total = 512 bytes) or until less than 128 bytes are read (request should be completely read)
它适用于 firefox 或 chrome 等浏览器以及使用该技术的其他客户端。
现在我的问题是新方法要慢得多。对本地套接字的请求非常慢,以至于超时 2 秒的脚本超时请求(我不知道为什么)。也许我的代码中存在一些逻辑问题?
有没有更好的方法来读取 SSL 套接字?因为每秒有数百甚至上千个请求,而新的读取方法甚至会减慢 http 请求。
注意:ssl-socket 目前没有使用,在我解决这个问题之前不会使用。
我还尝试使用缓冲读取器逐行读取,因为我们在这里讨论的是 http,但服务器突然用完了文件描述符(限制为 20 000)。不过,可能是因为我的实现。
我很感谢关于这个问题的每一个建议。如果您需要有关代码的更多信息,请告诉我,我会尽快发布。
编辑:实际上,我对我正在尝试做的事情进行了更多思考,我意识到这归结为读取 HTTP header 。因此,最好的解决方案是逐行读取请求行(或逐字符读取字符),并在 x 行后停止读取或直到到达空行(标记标题的末尾)。我当前的方法是将 BufferedInputStream 放在套接字的 InputStream 周围,并使用由 BufferedReader “读取”的 InputStreamReader 读取它(问题:当我使用 BufferedReader 时使用 BufferedInputStream 是否有意义?)。此 BufferedReader 读取字符的请求字符,检测行尾 (\r\n) 并继续读取,直到达到超过 64 个字符的行,最多读取 8 行或达到空行(标记 HTTP header 的结尾)。明天我将测试我的实现并相应地编辑此编辑。
编辑:我差点忘了在这里写下我的结果:有效。在每个 socket 上,甚至比以前的工作方式更快。感谢大家给我指出正确的方向。我最终是这样实现的:
List<String> requestLines = new ArrayList<String>(6);
InputStream is = this.cSocket.getInputStream();
bis = new BufferedInputStream(is, 1024);
InputStreamReader isr = new InputStreamReader(bis, Config.REQUEST_ENCODING);
BufferedReader br = new BufferedReader(isr);
/* read input character for character
* maximum line size is 768 characters
* maximum number of lines is 6
* lines are defined as char sequences ending with \r\n
* read lines are added to a list
* reading stops at the first empty line => HTTP header end
*/
int readChar; // the last read character
int characterCount = 0; // the character count in the line that is currently being read
int lineCount = 0; // the overall line count
char[] charBuffer = new char[768]; // create a character buffer with space for 768 characters (max line size)
// read as long as the stream is not closed / EOF, the character count in the current line is below 768 and the number of lines read is below 6
while((readChar = br.read()) != -1 && characterCount < 768 && lineCount < 6) {
charBuffer[characterCount] = (char) readChar; // fill the char buffer with the read character
if (readChar == '\n' && characterCount > 0 && charBuffer[characterCount-1] == '\r') { // if end of line is detected (\r\n)
if (characterCount == 1) { // if empty line
break; // stop reading after an empty line (HTTP header ended)
}
requestLines.add(new String(charBuffer, 0, characterCount-1)); // add the read line to the readLines list (and leave out the \r)
// charBuffer = new char[768]; // clear the buffer - not required
characterCount = 0; // reset character count for next line
lineCount++; // increase read line count
} else {
characterCount++; // if not end of line, increase read character count
}
}
最佳答案
这很可能更慢,因为您正在等待另一端发送更多数据,可能是它永远不会发送的数据。
更好的方法是给它一个更大的缓冲区,例如 32KB(128 很小),并且只读取一次可用的数据。如果此数据需要在某种消息中重新组合,则不应使用超时或固定数量的循环,因为 read() 只能保证至少返回一个字节。
关于java - 从 SSLSocket 读取最快或最好的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19715159/
我正在为一个系统编写 Android 客户端,该系统需要我打开一个 SSLSocket 到代理服务器,进行隧道握手,然后在隧道上创建另一个 SSLSocket。这是我创建隧道的代码: SSLS
我正在尝试在 Android 应用中的另一个 SSLSocket 之上创建一个 SSLSocket。较低的连接是到 Secure Web Proxy 的 SSL 安全连接。 (基于 SSL 的 HTT
我正在尝试创建一个 TLS 客户端,它将向任何 https 服务器发送 GET 请求。但是,当服务器尝试第二次或更多次发送 GET 请求时,没有来自服务器的输入。我不明白为什么它会跳过其他响应。 客户
更好地理解 TLS 机制。 我想知道我的服务器及其每个客户端在握手后同意使用的密码套件是什么。但是,我在网上找不到任何方法或任何信息来执行此操作。 我有 Java 服务器并可以访问 SSLSocket
我有一个 Java 服务器需要关闭所有连接的选项。作为其中的一部分,我在每个客户端套接字上调用 close() 。我遇到的问题是这个调用有时会无限期地阻塞。 我只能通过模拟数百个用户来重现这一点,因此
我正在尝试找到一种使用 SSL 在 Java 客户端和 C 服务器之间建立连接的方法。 这是java客户端: import java.io.BufferedWriter; import java.io
我正在尝试让我的 java 客户端使用 SSL 与 C 服务器通信。 问题是 - 我没有任何服务器源并且我收到握手失败错误: Exception in thread "main" javax.net.
我目前正在为一个学校项目开发 Java 服务器平台。我正在使用 SSL TCP 套接字进行通信,我正处于开发客户端和服务器之间的 JSon 协议(protocol)的阶段。 我的问题是协议(proto
我正在尝试在 Java 中将 SSL 与 IMAP 结合使用。我不想使用 IMAP 类。出于某种原因,当我发送第 n 条消息时,我收到了消息 n-2 的回复,而不是消息 n-1 的回复。这意味着在发送
我正在编写一个客户端-服务器聊天应用程序。我想加密这两者之间的连接。我第一次这样做,我觉得很难。据我了解,我需要一个用于客户端的信任库和一个用于服务器的 keystore 。我已按照本指南生成它们:h
我在 StackOverflow 上到处搜索,但这些问题似乎与我的不同,我在修复它时遇到了很多麻烦。 现在,我的程序应该只使用 SSL 套接字建立客户端-服务器连接,客户端只发送一条消息并关闭(稍后我
我为我的 Android 应用程序使用 SSLSocket根据这篇文章,SSLSocket 不执行主机名验证 here 而且我在使用 IP 而不是域时没有看到任何异常,并且一切正常那么我可以使用 IP
我目前正在开发一个 Android 应用程序,我需要在该应用程序上执行连接到测试服务器的 SSLSocket。 问题是我们不会为该服务器购买证书,因为它是测试服务器,而不是生产服务器。 虽然它在模拟器
在 JSSE 文档中,它只是说 sslsocket 可以由 SSLSocketFactory 通过调用 createSocket 创建。但是它没有描述如何调用 ssl 握手,如何传递 key Mate
如何在创建 SSLSocket 时设置本地端口? 这是我创建套接字的方式: SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.
我想用 Java 实现一个 SSL 代理。我基本上开了两个socket browser-proxy , proxy-server ,并运行两个线程来写入 proxy-server他们阅读的内容 bro
有没有办法让 SSLSocket 在不使用 addHandshakeListener() 方法的情况下等待握手完成?我希望它在完成握手之前一直阻塞。 编辑:稍微澄清一下:最初使用常规(非 SSL)套接
我正在从 SSL 套接字读取,但主机与证书不匹配(例如 host = "localhost")。我预计会出现异常,但以下代码很高兴地与远程服务器对话,没有任何问题。 try ( final S
有一个普通的套接字服务器监听端口12345; ServerSocket s = new ServerSocket(12345); 我想知道的是,有可能: 如果客户端发送http请求,服务器直接处理请求
我正在尝试使用协议(protocol) TLSv1.2 通过 SSLSocket 连接服务器。服务器仅支持以下密码。 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-A
我是一名优秀的程序员,十分优秀!