📄 serversocketthread.java
字号:
byte finalPacket[] = clientHandler.getFinalPacket(termError != null); this.writeBytes(output, finalPacket); } catch (Throwable t) { Print.logException("Final packet transmission", t); } clientHandler.sessionTerminated(termError, this.readByteCount, this.writeByteCount); } /* flush output before closing */ if (output != null) { try { output.flush(); } catch (IOException ioe) { Print.logException("Flush", ioe); } catch (Throwable t) { Print.logException("?", t); } } /* linger on close */ try { this.client.setSoLinger(ServerSocketThread.this.getLingerTimeoutSec()); // (seconds) } catch (SocketException se) { Print.logException("setSoLinger", se); } catch (Throwable t) { Print.logException("?", t); } /* close socket */ try { this.client.close(); } catch (IOException ioe) { /* unable to close? */ } /* clear for next requestor */ synchronized (this.runLock) { this.client = null; } } // while (true) } // run() private void writeBytes(OutputStream output, byte cmd[]) throws IOException { if ((output != null) && (cmd != null) && (cmd.length > 0)) { try { String c = StringTools.toStringValue(cmd); //Print.logDebug("<-- [" + c.length() + "] " + c); output.write(cmd); output.flush(); this.writeByteCount += cmd.length; } catch (IOException t) { Print.logError("writeBytes error - " + t); throw t; } } } private int readByte(ClientSocket client, long timeoutAt, int byteNdx) throws IOException { // Read until: // - Timeout // - IO error // - Read byte int ch; InputStream input = client.getInputStream(); while (true) { if (timeoutAt > 0L) { long currentTimeMS = DateTime.getCurrentTimeMillis(); if (currentTimeMS >= timeoutAt) { throw new SSReadTimeoutException("Read timeout [@ " + byteNdx + "]"); } //if (input.available() <= 0) { int timeout = (int)(timeoutAt - currentTimeMS); client.setSoTimeout(timeout); //} } try { // this read is expected to time-out if no data is available ch = input.read(); if (ch < 0) { // socket likely closed by client throw new SSEndOfStreamException("End of stream [@ " + byteNdx + "]"); } this.readByteCount++; return ch; // <-- valid character returned } catch (InterruptedIOException ie) { // timeout continue; } catch (SocketException se) { // rethrow IO error throw se; } catch (IOException ioe) { // rethrow IO error throw ioe; } } } private byte[] readLine(ClientSocket client, ClientPacketHandler clientHandler) throws IOException { // Read until: // - EOL // - Timeout // - IO error // - Read 'maxLen' characters /* timeouts */ long idleTimeoutMS = ServerSocketThread.this.getIdleTimeout(); long pcktTimeoutMS = ServerSocketThread.this.getPacketTimeout(); long pcktTimeoutAt = (idleTimeoutMS > 0L)? (DateTime.getCurrentTimeMillis() + idleTimeoutMS) : -1L; /* max read length */ int maxLen = ServerSocketThread.this.getMaximumPacketLength(); // no minimum /* set default socket timeout */ client.setSoTimeout(10000); /* packet */ byte buff[] = new byte[maxLen]; int buffLen = 0; boolean isIdle = true; long readStartTime = DateTime.getCurrentTimeMillis(); try { while (true) { /* read byte */ int ch = this.readByte(client, pcktTimeoutAt, buffLen); // valid character returned /* reset idle timeout */ if (isIdle) { isIdle = false; if (pcktTimeoutMS > 0L) { // reset timeout pcktTimeoutAt = DateTime.getCurrentTimeMillis() + pcktTimeoutMS; } } /* check special characters */ if (ServerSocketThread.this.isLineTerminatorChar(ch)) { // end of line (typically '\n') break; } else if (ServerSocketThread.this.isIgnoreChar(ch)) { // ignore this character (typically '\r') continue; } else if (ServerSocketThread.this.isBackspaceChar(ch)) { if (buffLen > 0) { buffLen--; } continue; } else if (ch < ' ') { // ignore non-printable characters continue; } /* save byte */ if (buffLen >= buff.length) { // overflow? byte newBuff[] = new byte[buff.length * 2]; System.arraycopy(buff, 0, newBuff, 0, buff.length); buff = newBuff; } buff[buffLen++] = (byte)ch; /* check lengths */ if ((maxLen > 0) && (buffLen >= maxLen)) { // we've read all the bytes we can break; } } } catch (SSReadTimeoutException te) { // This could mean a protocol error if (buffLen > 0) { String s = StringTools.toStringValue(buff, 0, buffLen); Print.logWarn("Timeout: " + s); } if (ServerSocketThread.this.getTerminateOnTimeout()) { throw te; } } catch (SSEndOfStreamException eos) { // This could mean a protocol error if (buffLen > 0) { String s = StringTools.toStringValue(buff, 0, buffLen); Print.logWarn("EOS: " + s); } if (client.isTCP()) { // readLine Print.logError(eos.getMessage()); throw eos; } else { // We're at the end of the UDP datastream // (just fall through to return what bytes we've already read.) } } catch (IOException ioe) { Print.logError("ReadLine error - " + ioe); throw ioe; } long readEndTime = DateTime.getCurrentTimeMillis(); /* return packet */ if (buff.length == buffLen) { // highly unlikely return buff; } else { // resize buffer byte newBuff[] = new byte[buffLen]; System.arraycopy(buff, 0, newBuff, 0, buffLen); return newBuff; } } private byte[] readPacket(ClientSocket client, ClientPacketHandler clientHandler) throws IOException { // Read until: // - Timeout // - IO error // - Read 'maxLen' characters // - Read 'actualLen' characters /* timeouts */ long idleTimeoutMS = ServerSocketThread.this.getIdleTimeout(); long pcktTimeoutMS = ServerSocketThread.this.getPacketTimeout(); long pcktTimeoutAt = (idleTimeoutMS > 0L)? (DateTime.getCurrentTimeMillis() + idleTimeoutMS) : -1L; /* packet/read length */ int maxLen = ServerSocketThread.this.getMaximumPacketLength(); int minLen = ServerSocketThread.this.getMinimumPacketLength(); int actualLen = 0; /* set default socket timeout */ client.setSoTimeout(10000); /* packet */ byte packet[] = new byte[maxLen]; int packetLen = 0; boolean isIdle = true; boolean isTextLine = false; try { while (true) { /* read byte */ int ch = this.readByte(client, pcktTimeoutAt, packetLen); // valid character returned /* reset idle timeout */ if (isIdle) { isIdle = false; if (pcktTimeoutMS > 0L) { // reset packet timeout pcktTimeoutAt = DateTime.getCurrentTimeMillis() + pcktTimeoutMS; } } /* look for line terminator? */ if (isTextLine) { if (ServerSocketThread.this.isLineTerminatorChar(ch)) { // end of line (typically '\n') break; } else if (ServerSocketThread.this.isIgnoreChar(ch)) { // ignore this character (typically '\r') continue; } else { // save byte packet[packetLen++] = (byte)ch; } } else { // save byte packet[packetLen++] = (byte)ch; } /* check lengths */ if (packetLen >= maxLen) { // we've read all the bytes we can break; } else if ((actualLen > 0) && (packetLen >= actualLen)) { // we've read the bytes we expected to read break; } else if ((clientHandler != null) && (actualLen <= 0) && (packetLen >= minLen)) { // we've read the minimum number of bytes // get the actual expected packet length actualLen = clientHandler.getActualPacketLength(packet, packetLen); if (actualLen == PACKET_LEN_ASCII_LINE_TERMINATOR) { // look for line terminator character actualLen = maxLen; isTextLine = true; } else if (actualLen <= PACKET_LEN_END_OF_STREAM) { // read the rest of the stream actualLen = maxLen; } else if (actualLen > maxLen) { Print.logStackTrace("Actual length [" + actualLen + "] > Maximum length [" + maxLen + "]"); actualLen = maxLen; } else { //Print.logDebug("New actual packet len: " + actualLen); } // check to see if we've already read everything we need to if (actualLen == packetLen) { // we already have exactly what we need break; } } } } catch (SSReadTimeoutException t) { // This could mean a protocol error if (packetLen > 0) { String h = StringTools.toHexString(packet, 0, packetLen); Print.logWarn("Timout: " + h); } if (ServerSocketThread.this.getTerminateOnTimeout()) { throw t; } } catch (SSEndOfStreamException eos) { // This could mean a protocol error if (packetLen > 0) { String h = StringTools.toHexString(packet, 0, packetLen); Print.logWarn("EOS: " + h); } if (client.isTCP()) { // readPacket Print.logError(eos.getMessage()); throw eos; } else { // We're at the end of the UDP datastream // (just fall through to return what bytes we've already read.) } } catch (SocketException se) { Print.logError("ReadPacket error - " + se); throw se; } catch (IOException ioe) { Print.logError("ReadPacket error - " + ioe); throw ioe; } /* return packet */ if (packet.length == packetLen) { // highly unlikely return packet; } else { // resize buffer byte newPacket[] = new byte[packetLen]; System.arraycopy(packet, 0, newPacket, 0, packetLen); return newPacket; } } public void close() throws IOException { IOException rethrowIOE = null; synchronized (this.runLock) { if (this.client != null) { try { this.client.close(); } catch (IOException ioe) { /* unable to close? */ rethrowIOE = ioe; } this.client = null; } } if (rethrowIOE != null) { throw rethrowIOE; } } } // ------------------------------------------------------------------------ public static class SSSessionTimeoutException extends IOException { public SSSessionTimeoutException(String msg) { super(msg); } } public static class SSReadTimeoutException extends IOException { public SSReadTimeoutException(String msg) { super(msg); } } public static class SSEndOfStreamException extends IOException { public SSEndOfStreamException(String msg) { super(msg); } } // ------------------------------------------------------------------------ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -