📄 ftpcontrolsocket.java
字号:
bytes[0] = (byte) (value >> 8); // bits 1- 8
bytes[1] = (byte) (value & 0x00FF); // bits 9-16
return bytes;
}
/**
* Sets the data port on the server, i.e. sends a PORT
* command
*
* @param host the local host the server will connect to
* @param portNo the port number to connect to
*/
private void setDataPort(InetAddress host, short portNo)
throws IOException, FTPException {
byte[] hostBytes = host.getAddress();
byte[] portBytes = toByteArray(portNo);
// assemble the PORT command
String cmd = new StringBuffer ("PORT ")
.append (toUnsignedShort (hostBytes[0])) .append (",")
.append (toUnsignedShort (hostBytes[1])) .append (",")
.append (toUnsignedShort (hostBytes[2])) .append (",")
.append (toUnsignedShort (hostBytes[3])) .append (",")
.append (toUnsignedShort (portBytes[0])) .append (",")
.append (toUnsignedShort (portBytes[1])) .toString ();
// send command and check reply
FTPReply reply = sendCommand(cmd);
validateReply(reply, "200");
}
/**
* Request a data socket be created on the
* server, connect to it and return our
* connected socket.
*
* @return connected data socket
*/
FTPDataSocket createDataSocketPASV()
throws IOException, FTPException {
// PASSIVE command - tells the server to listen for
// a connection attempt rather than initiating it
FTPReply replyObj = sendCommand("PASV");
validateReply(replyObj, "227");
String reply = replyObj.getReplyText();
// 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(')');
// allow for IBM missing brackets around IP address
if (startIP < 0 && endIP < 0) {
startIP = reply.toUpperCase().lastIndexOf("MODE") + 4;
endIP = reply.length();
}
String ipData = reply.substring(startIP+1,endIP);
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 != ',') {
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);
}
}
}
// assemble the IP address
// we try connecting, so we don't bother checking digits etc
String ipAddress = parts[0] + "."+ parts[1]+ "." +
parts[2] + "." + parts[3];
// assemble the port number
int port = (parts[4] << 8) + parts[5];
// create the socket
return newPassiveDataSocket(ipAddress, port);
}
/**
* 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 {
return new FTPActiveDataSocket(new ServerSocket(port));
}
/**
* 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 muliline response, and the last line starts
* with the same 3 digit code.
*
* @return structured reply object
*/
FTPReply readReply()
throws IOException {
String line = reader.readLine();
if (line == null || line.length() == 0)
throw new IOException("Unexpected null reply received");
log(line, false);
String replyCode = line.substring(0, 3);
StringBuffer reply = new StringBuffer("");
if (line.length() > 3)
reply.append(line.substring(4));
Vector dataLines = null;
// check for multiline response and build up
// the reply
if (line.charAt(3) == '-') {
dataLines = new Vector();
boolean complete = false;
while (!complete) {
line = reader.readLine();
if (line == null)
throw new IOException("Unexpected null reply received");
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
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
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) {
String replyCode = reply.getReplyCode();
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 + -