Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 读取SSLSocket的最快或最佳方式_Java_Sockets_Ssl_Https_Serversocket - Fatal编程技术网

Java 读取SSLSocket的最快或最佳方式

Java 读取SSLSocket的最快或最佳方式,java,sockets,ssl,https,serversocket,Java,Sockets,Ssl,Https,Serversocket,我正在运行一个多线程的最低限度http(s)服务器(虽然不是web服务器),它接受三个服务器套接字上的连接:本地、internet和internet ssl 每个套接字的so超时为1000毫秒(将来可能会降低) 工作线程读取如下请求: byte[] reqBuffer = new byte[512]; theSocket.getInputStream().read(reqBuffer); byte[] reqBuffer = new byte[512]; InputStream is = th

我正在运行一个多线程的最低限度http(s)服务器(虽然不是web服务器),它接受三个服务器套接字上的连接:本地、internet和internet ssl

每个套接字的so超时为1000毫秒(将来可能会降低)

工作线程读取如下请求:

byte[] reqBuffer = new byte[512];
theSocket.getInputStream().read(reqBuffer);
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)
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
    }
}
现在的问题是,对于新实现的ssl套接字,出现了1/n-1记录拆分技术的问题。还有一些客户端在使用ssl(4/n-4等)时以其他奇怪的方式分裂,所以我想我可能只是执行如下多个读取:

byte[] reqBuffer = new byte[512];
theSocket.getInputStream().read(reqBuffer);
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)
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
    }
}
byte[]reqBuffer=新字节[512];
InputStream是=socket.getInputStream();
int read=is.read(reqBuffer,0,128);//初始读取-对于x/n-x,这是非常小的
int pos=0;
如果(读取>0){
pos=读取;
}
int i=0;
做{
read=is.read(reqBuffer,位置128);
如果(读取>0){
pos+=读取;
}
i++;
}while(read==128&&i<3);//最多再读取3次(总共4次=512字节)或直到读取的字节数少于128字节(应完全读取请求)
它适用于firefox或chrome等浏览器以及其他使用该技术的客户端

现在我的问题是新方法要慢得多。对本地套接字的请求非常慢,以至于有2秒超时的脚本在请求时超时(我不知道为什么)。也许我的代码中有一些逻辑问题

有没有更好的方法读取SSL套接字?因为每秒有数百甚至1000个请求,而新的读取方法甚至会降低http请求的速度

注意:ssl套接字目前不在使用中,在解决此问题之前不会使用

我也尝试过使用缓冲读取器逐行读取,因为我们在这里讨论的是http,但是服务器的文件描述符用完了(限制为20000)。可能是因为我的实现

我非常感谢关于这个问题的每一个建议。如果你需要更多关于代码的信息,请告诉我,我会尽快发布

编辑: 实际上,我对我要做的事情多考虑了一点,我意识到这可以归结为读取HTTP头。因此,最好的解决方案是以行为单位(或以字符为单位)实际读取请求行,并在x行之后或直到到达空行(标记标头的结尾)时停止读取。 我目前的方法是在套接字的InputStream周围放置一个BufferedInputStream,并使用由BufferedReader“读取”的InputStreamReader读取它(问题:当我使用BufferedReader时使用BufferedInputStream有意义吗?)。 此BufferedReader读取每个字符的请求字符,检测行尾(\r\n)并继续读取,直到达到长度超过64个字符的行、最多读取8行或达到空行(标记HTTP标头的结尾)。明天我将测试我的实现并相应地编辑此编辑

编辑: 我差点忘了在这里写我的结果:它是有效的。在每个插座上,甚至比以前的工作方式更快。谢谢大家为我指明了正确的方向。我最终实现了如下:

byte[] reqBuffer = new byte[512];
theSocket.getInputStream().read(reqBuffer);
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)
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
    }
}
List requestLines=newarraylist(6);
InputStream is=this.cSocket.getInputStream();
bis=新的BufferedInputStream(is,1024);
InputStreamReader isr=新的InputStreamReader(bis,配置请求编码);
BufferedReader br=新的BufferedReader(isr);
/*逐字符读取输入字符
*最大行大小为768个字符
*最大行数为6
*行定义为以结尾的字符序列\r\n
*读取行被添加到列表中
*读取在第一个空行处停止=>HTTP头端
*/
int readChar;//最后读取的字符
int characterCount=0;//当前正在读取的行中的字符计数
int lineCount=0;//总行数
char[]charBuffer=新字符[768];//创建一个可容纳768个字符的字符缓冲区(最大行大小)
//只要流未关闭/EOF,则读取,当前行中的字符计数低于768,读取的行数低于6
while((readChar=br.read())!=-1&&characterCount<768&&lineCount<6){
charBuffer[characterCount]=(char)readChar;//用读取字符填充char缓冲区
如果(readChar='\n'&&characterCount>0&&charBuffer[characterCount-1]='\r'){//如果检测到行尾(\r\n)
if(characterCount==1){//if空行
break;//空行后停止读取(HTTP头结束)
}
requestLines.add(新字符串(charBuffer,0,characterCount-1));//将读取行添加到读取行列表中(并省略\r)
//charBuffer=new char[768];//清除缓冲区-不是必需的
characterCount=0;//重置下一行的字符计数
lineCount++;//增加读取行数
}否则{
characterCount++;//如果不是行尾,则增加读取字符数
}
}

这很可能较慢,因为您正在等待另一端发送更多数据,可能是它永远不会发送的数据

更好的方法是给它一个更大的缓冲区,比如32KB(128小),并且只读取一次可用的数据。如果需要在某种类型的消息中重新组合此数据,则不应使用超时或固定数量的循环,因为read()只保证返回至少一个字节。

您当然应该在SSLSocket的输入流周围包装一个BufferedInputStream

一次读取128字节并推进偏移量的技术完全没有意义。一次尽可能多地阅读并处理它。或者一次从缓冲流中提取一个字节


类似地,您当然应该将SSLSocket的输出流包装在BufferedOutputStream中。

是的,这可能是问题所在,也是我停止的原因