📄 ftpcontrolsocket.java
字号:
}
// create the socket
return newPassiveDataSocket(hostIP, port);
}
/**
* Get the parts that make up the PASV reply
*
* @param reply reply string
* @return
* @throws FTPException
*/
int[] getPASVParts(String reply) throws FTPException {
// The reply to PASV is in the form:
// 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).
// where h1..h4 are the IP address to connect and
// p1,p2 the port number
// Example:
// 227 Entering Passive Mode (128,3,122,1,15,87).
// NOTE: PASV command in IBM/Mainframe returns the string
// 227 Entering Passive Mode 128,3,122,1,15,87 (missing
// brackets)
// extract the IP data string from between the brackets
int startIP = reply.indexOf('(');
int endIP = reply.indexOf(')');
// if didn't find start bracket, figure out where it should have been
if (startIP < 0) {
startIP = 0;
while (startIP < reply.length() && !Character.isDigit(reply.charAt(startIP)))
startIP++;
startIP--; // go back so this is where the '(' should be
}
// if didn't find end bracket, set to end of reply
if (endIP < 0) {
endIP = reply.length()-1;
while (endIP > 0 && !Character.isDigit(reply.charAt(endIP)))
endIP--;
endIP++; // go forward so this is where the ')' should be
if (endIP >= reply.length())
reply += ")";
}
String ipData = reply.substring(startIP+1,endIP).trim();
int parts[] = new int[6];
int len = ipData.length();
int partCount = 0;
StringBuffer buf = new StringBuffer();
// loop thru and examine each char
for (int i = 0; i < len && partCount <= 6; i++) {
char ch = ipData.charAt(i);
if (Character.isDigit(ch))
buf.append(ch);
else if (ch != ',' && ch != ' ') {
throw new FTPException("Malformed PASV reply: " + reply);
}
// get the part
if (ch == ',' || i+1 == len) { // at end or at separator
try {
parts[partCount++] = Integer.parseInt(buf.toString());
buf.setLength(0);
}
catch (NumberFormatException ex) {
throw new FTPException("Malformed PASV reply: " + reply);
}
}
}
return parts;
}
/**
* Constructs a new <code>FTPDataSocket</code> object (client mode) and connect
* to the given remote host and port number.
*
* @param remoteHost Remote host to connect to.
* @param port Remote port to connect to.
* @return A new <code>FTPDataSocket</code> object (client mode) which is
* connected to the given server.
* @throws IOException Thrown if no TCP/IP connection could be made.
*/
protected FTPDataSocket newPassiveDataSocket(String remoteHost, int port)
throws IOException {
return new FTPPassiveDataSocket(new Socket(remoteHost, port));
}
/**
* Constructs a new <code>FTPDataSocket</code> object (server mode) which will
* listen on the given port number.
*
* @param port Remote port to listen on.
* @return A new <code>FTPDataSocket</code> object (server mode) which is
* configured to listen on the given port.
* @throws IOException Thrown if an error occurred when creating the socket.
*/
protected FTPDataSocket newActiveDataSocket(int port)
throws IOException {
// ensure server sock gets the timeout
ServerSocket sock = listenOnAllInterfaces ?
new ServerSocket(port) : new ServerSocket(port, 0, controlSock.getLocalAddress());
log.debug("ListenOnAllInterfaces=" + listenOnAllInterfaces);
sock.setSoTimeout(controlSock.getSoTimeout());
return new FTPActiveDataSocket(sock);
}
/**
* Send a command to the FTP server and
* return the server's reply as a structured
* reply object
*
* @param command command to send
*
* @return reply to the supplied command
*/
public FTPReply sendCommand(String command)
throws IOException {
writeCommand(command);
// and read the result
return readReply();
}
/**
* Send a command to the FTP server. Don't
* read the reply
*
* @param command command to send
*/
void writeCommand(String command)
throws IOException {
log(DEBUG_ARROW + command, true);
// send it
writer.write(command + EOL);
writer.flush();
}
/**
* Read the FTP server's reply to a previously
* issued command. RFC 959 states that a reply
* consists of the 3 digit code followed by text.
* The 3 digit code is followed by a hyphen if it
* is a multiline response, and the last line starts
* with the same 3 digit code.
*
* @return structured reply object
*/
FTPReply readReply()
throws IOException {
String line = reader.readLine();
while (line != null && line.length() == 0)
line = reader.readLine();
if (line == null) {
String msg = "Control channel unexpectedly closed";
log.error(msg);
throw new IOException(msg);
}
log(line, false);
if (line.length() < 3) {
String msg = "Short reply received (" + line + ")";
log.error(msg);
throw new IOException(msg);
}
String replyCode = line.substring(0, 3);
StringBuffer reply = new StringBuffer("");
if (line.length() > 3)
reply.append(line.substring(4));
Vector dataLines = null;
// check for multi-line response and build up
// the reply
if (line.charAt(3) == '-') {
dataLines = new Vector();
boolean complete = false;
while (!complete) {
line = reader.readLine();
if (line == null){
String msg = "Control channel unexpectedly closed";
log.error(msg);
throw new IOException(msg);
}
if (line.length() == 0)
continue;
log(line, false);
if (line.length() > 3 &&
line.substring(0, 3).equals(replyCode) &&
line.charAt(3) == ' ') {
reply.append(line.substring(3));
complete = true;
}
else { // not the last line
reply.append(" ").append(line);
dataLines.addElement(line);
}
} // end while
} // end if
if (dataLines != null) {
String[] data = new String[dataLines.size()];
dataLines.copyInto(data);
return new FTPReply(replyCode, reply.toString(), data);
}
else {
return new FTPReply(replyCode, reply.toString());
}
}
/**
* Validate the response the host has supplied against the
* expected reply. If we get an unexpected reply we throw an
* exception, setting the message to that returned by the
* FTP server
*
* @param reply the entire reply string we received
* @param expectedReplyCode the reply we expected to receive
*
*/
FTPReply validateReply(String reply, String expectedReplyCode)
throws FTPException {
FTPReply replyObj = new FTPReply(reply);
if (validateReplyCode(replyObj, expectedReplyCode))
return replyObj;
// if unexpected reply, throw an exception
throw new FTPException(replyObj);
}
/**
* Validate the response the host has supplied against the
* expected reply. If we get an unexpected reply we throw an
* exception, setting the message to that returned by the
* FTP server
*
* @param reply the entire reply string we received
* @param expectedReplyCodes array of expected replies
* @return an object encapsulating the server's reply
*
*/
public FTPReply validateReply(String reply, String[] expectedReplyCodes)
throws IOException, FTPException {
FTPReply replyObj = new FTPReply(reply);
return validateReply(replyObj, expectedReplyCodes);
}
/**
* Validate the response the host has supplied against the
* expected reply. If we get an unexpected reply we throw an
* exception, setting the message to that returned by the
* FTP server
*
* @param reply reply object
* @param expectedReplyCodes array of expected replies
* @return reply object
*
*/
public FTPReply validateReply(FTPReply reply, String[] expectedReplyCodes)
throws FTPException {
for (int i = 0; i < expectedReplyCodes.length; i++)
if (validateReplyCode(reply, expectedReplyCodes[i]))
return reply;
// got this far, not recognised
StringBuffer buf = new StringBuffer("[");
for (int i = 0; i < expectedReplyCodes.length; i++) {
buf.append(expectedReplyCodes[i]);
if (i+1 < expectedReplyCodes.length)
buf.append(",");
}
buf.append("]");
log.info("Expected reply codes = " + buf.toString());
throw new FTPException(reply);
}
/**
* Validate the response the host has supplied against the
* expected reply. If we get an unexpected reply we throw an
* exception, setting the message to that returned by the
* FTP server
*
* @param reply reply object
* @param expectedReplyCode expected reply
* @return reply object
*
*/
public FTPReply validateReply(FTPReply reply, String expectedReplyCode)
throws FTPException {
if (validateReplyCode(reply, expectedReplyCode))
return reply;
// got this far, not recognised
log.info("Expected reply code = [" + expectedReplyCode + "]");
throw new FTPException(reply);
}
/**
* Validate reply object
*
* @param reply reference to reply object
* @param expectedReplyCode expect reply code
* @return true if valid, false if invalid
*/
private boolean validateReplyCode(FTPReply reply, String expectedReplyCode)
throws FTPConnectionClosedException {
String replyCode = reply.getReplyCode();
if ("421".equals(replyCode)) {
throw new FTPConnectionClosedException(reply.getReplyText());
}
if (strictReturnCodes) {
if (replyCode.equals(expectedReplyCode))
return true;
else
return false;
}
else { // non-strict - match first char
if (replyCode.charAt(0) == expectedReplyCode.charAt(0))
return true;
else
return false;
}
}
/**
* Log a message, checking for passwords
*
* @param msg message to log
* @param reply true if a response, false otherwise
*/
void log(String msg, boolean command) {
if (msg.startsWith(PASSWORD_MESSAGE))
msg = PASSWORD_MESSAGE + " ********";
log.debug(msg);
if (messageListener != null)
if (command)
messageListener.logCommand(msg);
else
messageListener.logReply(msg);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -