Java - 套接字 - 显示服务器上所有文件的名称
Java - Sockets - display names of all files on server
我正在尝试制作仅使用套接字的 ftpclient。我正在与服务器建立连接,但不知道如何显示文件。这是我的代码:
package pl.edu.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;
import pl.edu.config.ConfigData;
public class FTPProtocol {
private Socket socket;
private BufferedReader reader;
private OutputStreamWriter writer;
private Socket socket2;
private BufferedReader reader2;
private OutputStreamWriter writer2;
private String serverImportantOutput;
private boolean firstSocket = true;
public void makeConnection(ConfigData configData) throws UnknownHostException, IOException, InterruptedException {
socket = new Socket(configData.getServerAddress(), configData.getPort());
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new OutputStreamWriter(socket.getOutputStream());
(new Thread(new Runnable() {
public void run() {
try {
String line;
if (firstSocket == true) {
while ((line = reader.readLine()) != null) {
System.out.println("SERVER: " + line);
if (line.startsWith("227 Entering Passive Mode")) {
serverImportantOutput = line;
}
}
} else {
while ((line = reader.readLine()) != null) {
System.out.println("SERVER: " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
})).start();
Thread.sleep(2000);
sendCommand("USER " + configData.getUsername());
sendCommand("PASS " + configData.getPassword());
sendCommand("SYST");
sendCommand("FEAT");
sendCommand("PWD");
sendCommand("TYPE I");
sendCommand("PWD");
List<String> newData = sendCommandPasv("PASV");
socket2 = new Socket(newData.get(0), Integer.parseInt(newData.get(1)));
reader2 = new BufferedReader(new InputStreamReader(socket2.getInputStream()));
writer2 = new OutputStreamWriter(socket2.getOutputStream());
sendCommand2("LIST");
}
private void sendCommand(String command) throws IOException, InterruptedException {
firstSocket = true;
writer.write(command + "\r\n");
writer.flush();
System.out.println("Client:" + command);
Thread.sleep(2000);
}
private void sendCommand2(String command) throws IOException, InterruptedException {
firstSocket = true;
writer2.write(command + "\r\n");
writer2.flush();
System.out.println("Client:" + command);
Thread.sleep(2000);
firstSocket = false;
Thread.sleep(2000);
}
private List<String> sendCommandPasv(String command) throws IOException, InterruptedException {
List<String> listOfStrings = new ArrayList<String>();
writer.write(command + "\r\n");
writer.flush();
System.out.println("Client:" + command);
Thread.sleep(2000);
String fullAdress = serverImportantOutput.substring(serverImportantOutput.indexOf("(") + 1,
serverImportantOutput.indexOf(")"));
List<String> partsOfAdress = Arrays.asList(fullAdress.replaceAll("\s+", "").split(","));
String host = partsOfAdress.get(0) + "." + partsOfAdress.get(1) + "." + partsOfAdress.get(2) + "."
+ partsOfAdress.get(3);
String port = Integer
.toString(Integer.parseInt(partsOfAdress.get(4)) * 256 + Integer.parseInt(partsOfAdress.get(5)));
System.out.println("Host: " + host);
System.out.println("Port: " + port);
listOfStrings.add(host);
listOfStrings.add(port);
return listOfStrings;
}
}
我尝试使用 LIST、NLST、MLSD,但仍然无济于事。在控制台中我有:
SERVER: 227 Entering Passive Mode (127,0,0,1,197,183)
Host: 127.0.0.1
Port: 50615
Client:LIST
而且"Client:LIST"我要等很久。之后我得到:
SERVER: 421 Connection timed out.
有人可能知道我做错了什么?
我现在编辑了这个方法:
private void sendCommand2(String command) throws IOException, InterruptedException {
writer.write(command + "\r\n");
writer.flush();
System.out.println("Client:" + command);
firstSocket = false;
Thread.sleep(2000);
}
现在结果是:
SERVER: 227 Entering Passive Mode (127,0,0,1,196,72)
Host: 127.0.0.1
Port: 50248
Client:LIST
SERVER: 150 Opening data channel for directory listing of "/"
SERVER: 226 Successfully transferred "/"
但是还是没有显示任何文件。
现在,当 "bool firstSocket" 为假时,我编辑为从 reader2 读取。所以它应该在发送 "LIST" 命令后从 "reader2" 读取,但它仍然没有显示。
(new Thread(new Runnable() {
public void run() {
try {
String line;
if (firstSocket == true) {
while ((line = reader.readLine()) != null) {
System.out.println("SERVER: " + line);
if (line.startsWith("227 Entering Passive Mode")) {
serverImportantOutput = line;
}
}
} else {
while ((line = reader2.readLine()) != null) {
System.out.println("SERVER: " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
})).start();
只有在收到对 LIST
命令的 1xx
响应后,您才能尝试连接到 PASV
响应中返回的 IP/port。
您必须将 LIST
命令发送到(主)控制连接,而不是数据连接。
阅读 RFC 959 了解详情。
我正在尝试制作仅使用套接字的 ftpclient。我正在与服务器建立连接,但不知道如何显示文件。这是我的代码:
package pl.edu.ftp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;
import pl.edu.config.ConfigData;
public class FTPProtocol {
private Socket socket;
private BufferedReader reader;
private OutputStreamWriter writer;
private Socket socket2;
private BufferedReader reader2;
private OutputStreamWriter writer2;
private String serverImportantOutput;
private boolean firstSocket = true;
public void makeConnection(ConfigData configData) throws UnknownHostException, IOException, InterruptedException {
socket = new Socket(configData.getServerAddress(), configData.getPort());
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new OutputStreamWriter(socket.getOutputStream());
(new Thread(new Runnable() {
public void run() {
try {
String line;
if (firstSocket == true) {
while ((line = reader.readLine()) != null) {
System.out.println("SERVER: " + line);
if (line.startsWith("227 Entering Passive Mode")) {
serverImportantOutput = line;
}
}
} else {
while ((line = reader.readLine()) != null) {
System.out.println("SERVER: " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
})).start();
Thread.sleep(2000);
sendCommand("USER " + configData.getUsername());
sendCommand("PASS " + configData.getPassword());
sendCommand("SYST");
sendCommand("FEAT");
sendCommand("PWD");
sendCommand("TYPE I");
sendCommand("PWD");
List<String> newData = sendCommandPasv("PASV");
socket2 = new Socket(newData.get(0), Integer.parseInt(newData.get(1)));
reader2 = new BufferedReader(new InputStreamReader(socket2.getInputStream()));
writer2 = new OutputStreamWriter(socket2.getOutputStream());
sendCommand2("LIST");
}
private void sendCommand(String command) throws IOException, InterruptedException {
firstSocket = true;
writer.write(command + "\r\n");
writer.flush();
System.out.println("Client:" + command);
Thread.sleep(2000);
}
private void sendCommand2(String command) throws IOException, InterruptedException {
firstSocket = true;
writer2.write(command + "\r\n");
writer2.flush();
System.out.println("Client:" + command);
Thread.sleep(2000);
firstSocket = false;
Thread.sleep(2000);
}
private List<String> sendCommandPasv(String command) throws IOException, InterruptedException {
List<String> listOfStrings = new ArrayList<String>();
writer.write(command + "\r\n");
writer.flush();
System.out.println("Client:" + command);
Thread.sleep(2000);
String fullAdress = serverImportantOutput.substring(serverImportantOutput.indexOf("(") + 1,
serverImportantOutput.indexOf(")"));
List<String> partsOfAdress = Arrays.asList(fullAdress.replaceAll("\s+", "").split(","));
String host = partsOfAdress.get(0) + "." + partsOfAdress.get(1) + "." + partsOfAdress.get(2) + "."
+ partsOfAdress.get(3);
String port = Integer
.toString(Integer.parseInt(partsOfAdress.get(4)) * 256 + Integer.parseInt(partsOfAdress.get(5)));
System.out.println("Host: " + host);
System.out.println("Port: " + port);
listOfStrings.add(host);
listOfStrings.add(port);
return listOfStrings;
}
}
我尝试使用 LIST、NLST、MLSD,但仍然无济于事。在控制台中我有:
SERVER: 227 Entering Passive Mode (127,0,0,1,197,183)
Host: 127.0.0.1
Port: 50615
Client:LIST
而且"Client:LIST"我要等很久。之后我得到:
SERVER: 421 Connection timed out.
有人可能知道我做错了什么?
我现在编辑了这个方法:
private void sendCommand2(String command) throws IOException, InterruptedException {
writer.write(command + "\r\n");
writer.flush();
System.out.println("Client:" + command);
firstSocket = false;
Thread.sleep(2000);
}
现在结果是:
SERVER: 227 Entering Passive Mode (127,0,0,1,196,72)
Host: 127.0.0.1
Port: 50248
Client:LIST
SERVER: 150 Opening data channel for directory listing of "/"
SERVER: 226 Successfully transferred "/"
但是还是没有显示任何文件。
现在,当 "bool firstSocket" 为假时,我编辑为从 reader2 读取。所以它应该在发送 "LIST" 命令后从 "reader2" 读取,但它仍然没有显示。
(new Thread(new Runnable() {
public void run() {
try {
String line;
if (firstSocket == true) {
while ((line = reader.readLine()) != null) {
System.out.println("SERVER: " + line);
if (line.startsWith("227 Entering Passive Mode")) {
serverImportantOutput = line;
}
}
} else {
while ((line = reader2.readLine()) != null) {
System.out.println("SERVER: " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
})).start();
只有在收到对 LIST
命令的 1xx
响应后,您才能尝试连接到 PASV
响应中返回的 IP/port。
您必须将 LIST
命令发送到(主)控制连接,而不是数据连接。
阅读 RFC 959 了解详情。