#java #android #ftp #android-networking #apache-commons-net
#java #Android #ftp #android-сеть #apache-commons-net
Вопрос:
Я пытаюсь подключиться к своему FTP, который работает на моем компьютере с Windows, через мое приложение для Android. Я не уверен, что происходит не так, поскольку тот же код работает в обычном Java-проекте.
Мой манифест имеет разрешение
<uses-permission android:name="android.permission.INTERNET"/>
Фрагмент запускает код подключения. Я пробовал apache и edtftpj, и у обоих одна и та же проблема.
Edtftpj
import com.enterprisedt.net.ftp.FTPConnectMode;
import com.enterprisedt.net.ftp.FTPException;
import com.enterprisedt.net.ftp.FileTransferClient;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
public class SecondFragment extends Fragment
{
private Activity mainActivity;
private EditText serverIPView, serverPortView;
private EditText serverUsernameView, serverPasswordView;
private Thread ftpThread = new Thread(new Runnable() {
@Override
public void run()
{
String serverHost = serverIPView.getText().toString();
String serverPort = serverPortView.getText().toString();
String username =serverUsernameView.getText().toString();
String password = serverPasswordView.getText().toString();
try {
FileTransferClient client = new FileTransferClient();
client.getAdvancedFTPSettings().setConnectMode(FTPConnectMode.PASV);
client.setRemoteHost("192.168.1.50");
client.setRemotePort(21);
client.setUserName(username);
client.setPassword(password);
Random rand = new Random();
byte[] bytes = new byte[1000];
rand.nextBytes(bytes);
client.connect();
OutputStream out = client.uploadStream("temp");
long begin = System.nanoTime();
out.write(bytes);
long end = System.nanoTime();
out.close();
client.deleteFile("temp");
client.disconnect();
double time = (double)(end - begin) / 1000000000;
Log.i("RunFTP", String.valueOf(time) " seconds");
} catch (IOException | FTPException e) {
e.printStackTrace();
}
}
});
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_second, container, false);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mainActivity = getActivity();
// get user text view of inputted server IP and port
serverIPView = view.findViewById(R.id.ftpSelectedIP);
serverPortView = view.findViewById(R.id.ftpSelectedPort);
// get user text views of inputted server credentials
serverUsernameView = view.findViewById(R.id.ftpSelectedUsername);
serverPasswordView = view.findViewById(R.id.ftpSelectedPassword);
Button runButton = view.findViewById(R.id.ftpRunButton);
runButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ftpThread.start();
try {
ftpThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
Apache Commons:
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
public class SecondFragment extends Fragment
{
private Activity mainActivity;
private EditText serverIPView, serverPortView;
private EditText serverUsernameView, serverPasswordView;
private Thread ftpThread = new Thread(new Runnable() {
@Override
public void run()
{
String username =serverUsernameView.getText().toString();
String password = serverPasswordView.getText().toString();
FTPClient ftp = new FTPClient();
try {
ftp.connect("192.168.1.50", 21);
ftp.login(username, password);
System.out.print(ftp.getReplyString());
int reply = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)) {
ftp.disconnect();
System.err.println("FTP server refused connection.");
System.exit(1);
}
Random rand = new Random();
byte[] bytes = new byte[1000];
rand.nextBytes(bytes);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setFileTransferMode(FTPClient.STREAM_TRANSFER_MODE);
ftp.enterLocalPassiveMode();
OutputStream out = ftp.storeFileStream("temp");
long begin = System.nanoTime();
out.write(bytes);
long end = System.nanoTime();
ftp.deleteFile("temp");
ftp.logout();
double time = (double)(end - begin) / 1000000000;
Log.i("RunFTP", String.valueOf(time) " seconds");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
});
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_second, container, false);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mainActivity = getActivity();
// get user text view of inputted server IP and port
serverIPView = view.findViewById(R.id.ftpSelectedIP);
serverPortView = view.findViewById(R.id.ftpSelectedPort);
// get user text views of inputted server credentials
serverUsernameView = view.findViewById(R.id.ftpSelectedUsername);
serverPasswordView = view.findViewById(R.id.ftpSelectedPassword);
Button runButton = view.findViewById(R.id.ftpRunButton);
runButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ftpThread.start();
try {
ftpThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
Ошибка:
W/System.err: java.net.SocketTimeoutException: failed to connect to /192.168.1.50 (port 21) from /100.96.240.94 (port 34106) after 60000ms
W/System.err: at libcore.io.IoBridge.connectErrno(IoBridge.java:191)
at libcore.io.IoBridge.connect(IoBridge.java:135)
W/System.err: at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
W/System.err: at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:621)
at com.enterprisedt.util.proxy.PlainSocket.createPlainSocket(PlainSocket.java:131)
at com.enterprisedt.net.ftp.FTPControlSocket.<init>(FTPControlSocket.java:415)
at com.enterprisedt.net.ftp.FTPClient.connect(FTPClient.java:1056)
W/System.err: at com.enterprisedt.net.ftp.FileTransferClient.connect(FileTransferClient.java:424)
at com.example.networkscanner.SecondFragment$1.run(SecondFragment.java:58)
at java.lang.Thread.run(Thread.java:919)
Мой FTP-сервер Windows. Все настроено, установлена переадресация портов, пробовал как подключаться к той же сети, так и на мобильном устройстве.
Есть идеи о том, что происходит? Я не уверен, что делать.
Комментарии:
1. Если вы загружаете FTP-приложение на свой телефон Android, может ли оно подключиться к вашему FTP-серверу? Где вы запускаете свой «обычный Java-проект» ?
2.
String serverHost = serverIPView.getText().toString();
Это не способ отправить код для справки, поскольку мы не знаем, что вводит пользователь. Лучше что-то вродеString serverHost = "192.168.3.12";
, но… Теперь я вижу, что вы даже не используете его. Не путайте нас!3. Отключите брандмауэр на своем ПК.
4. Пусть браузер на вашем устройстве Android попытается подключиться к этому ip.
5.
failed to connect to /192.168.1.50 (port 21) from /100.96.240.94
Это не очень похоже на попытку подключиться из той же сети. Конечно, мобильное соединение не будет работать с используемым ip. Пожалуйста, опубликуйте лучший журнал исключений.