I have read a half dozen threads regarding this and I'm no where closer to a solution. No matter what I change I get ftp return code 500 "The command was not accepted and the requested action did not take place." and I'm not sure how to debug that.
This is my site and I can connect with CoreFTP and read and write, so it does not seem to be a permissions issue. I've tried two different accounts, with this code and CoreFTP. One writes to the root and another is pointed to an "image_in" folder.
imageData is a byte array with a length of 166578 and stream has the same length after the InputStream call. storeFile() always returns false with a return code of 500.
One thread implied enterLocalPassiveMode() and enterRemotePassiveMode() were the culprits, but I have tried this code both with and without those lines and still I get a 500 return code.
Any idea what I'm missing?
Greg
class ImageUploadTask extends AsyncTask <Void, Void, String>{
#Override
protected String doInBackground(Void... unsued) {
try {
boolean status = false;
try {
FTPClient mFtpClient = new FTPClient();
String ip = "my domain dot com";
String userName = "ftp79815757-0";
String pass = "my password";
mFtpClient.connect(InetAddress.getByName(ip));
mFtpClient.login(userName, pass);
int reply = mFtpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
//one thread said this would do the trick
mFtpClient.enterLocalPassiveMode();
mFtpClient.enterRemotePassiveMode();
InputStream stream = new ByteArrayInputStream(imageData);
mFtpClient.changeWorkingDirectory("/images_in");
String currdir = mFtpClient.printWorkingDirectory();
if (!mFtpClient.storeFile("remoteName.jpg", stream)) {
Log.e("FTPUpload", String.valueOf(mFtpClient.getReplyCode()));
}
stream.close();
mFtpClient.disconnect();
}
else {
Log.e("FTPConnected", String.valueOf(reply));
}
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
} catch (Exception e) {
if (dialog.isShowing())
dialog.dismiss();
Toast.makeText(getApplicationContext(),
"Error",
Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
return null;
}
}
You forgot to set file type
mFtpClient.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
If it still doesn't work then you have following options:
If you insist on using Apache FTP Client then follow this example
Or you could try this example
The second example worked in my case.
You need to use: enterLocalPassiveMode
mFtpClient.enterLocalPassiveMode();
If you then do other operations, you might have to go back active with enterLocalActiveMode.
Related
i'm creating android application with Socket.io and node.js server.
My js server:
var http = require('http');
var server = http.createServer(function(req, res) {
});
var mysql = require('mysql');
var db = mysql.createConnection({
host:,
port:,
user:,
password:,
database:
});
var resultconnection = "";
db.connect(function(err){
if (err) {
resultconnection = err;
}
});
var io = require('socket.io').listen(server);
io.on('connection',function(socket){
console.log('Connected!');
socket.on("createaccount", function(data){
console.log('Create account executed.');
if(resultconnection != ""){
db.query("INSERT INTO USER (USERNAME, PASSWORD, EMAIL, BIRTHDATE) VALUES('"+data["username"]+"', SHA1('"+data["password"]+"'), '"+data["email"]+"', "+data["birthdate"]+"')");
resultconnection = "OK";
}
socket.emit('response', {"response": resultconnection});
});
});
server.listen(8080);
Android client(java):
try {
socket = IO.socket("http://localhost:8080");
socket.on("response", new Emitter.Listener() {
#Override
public void call(Object... args) {
JSONObject obj = (JSONObject) args[0];
try {
result = obj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
socket.connect();
JSONObject createUser = new JSONObject();
try {
createUser.put("username", username);
createUser.put("password", password);
createUser.put("email", email);
createUser.put("birthdate", datanasc);
} catch (JSONException e) {
e.printStackTrace();
}
socket.emit("createaccount", "");
} catch (URISyntaxException e) {
result = e.getMessage();
}
Console.log("Connected") is running but when I run the socket.emit("createaccount") the client does not run on the server.
I think the server IP you gave in the client code is not correct. It is trying to connect to the localhost of your Android device while your server is running on some other remote system.
Try changing the server IP in the following snippet(ideally this should be something other than localhost):
try {
socket = IO.socket("<server_IP:server_PORT");
socket.on("response", new Emitter.Listener() {
#Override
public void call(Object... args) {
JSONObject obj = (JSONObject) args[0];
try {
result = obj.getString("message");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
socket.connect();
JSONObject createUser = new JSONObject();
try {
createUser.put("username", username);
createUser.put("password", password);
createUser.put("email", email);
createUser.put("birthdate", datanasc);
} catch (JSONException e) {
e.printStackTrace();
}
socket.emit("createaccount", "");
} catch (URISyntaxException e) {
result = e.getMessage();
}
There are significant structural problems with how your server is designed:
You're trying to save resultconnection in a module global. That means you can only ever have one socket.io client connection that will work properly. The second connection will see the resultconnection from the previous client connection. There's just no way this is a proper way to do things. It could possibly work if you never ever had more than one client connect to your server - not just one client at a time, but one client all time.
The way you handle the async database operation in the createaccount message handler is just wrong. You are trying to .emit() the resultconnection back to the client before it has been set.
Your error handling for the db.connect() call does not seem correct. When you can't connect to the database you need to take some action, not just set a variable as such and proceed on as if nothing is wrong. Even that variable you set is being used wrong later. You're checking to see if you had an error on the connect and if you did, then you're trying to do a database operation. Besides just a messed up design, this logic is even backwards.
To think about how to fix the first issue, you need to explain what you're trying to do with this statement:
if(resultconnection != ""){
because that will need to be done a different way. You can't just save global state in your server and expect that to represent the state of any incoming connection.
How to fix the second issue will depend upon what is done for the first issue.
How to fix the third issue involves some design decisions about what to do with your server when you can't connect to the database (shut-down, retry, log, etc...).
I'm trying to get an authorization code via Google Plus login to use it on the server. The G+ login works, I am logged in on the device, but when I try to get the Token, I get an exception with the super helpful message Unknown. This is the code:
private class GoogleLoginTask extends AsyncTask<Void, Void, String> {
private static final String LOGIN_SCOPES =
"https://www.googleapis.com/auth/plus.login " +
"https://www.googleapis.com/auth/userinfo.email";
#Override
protected String doInBackground(Void[] params) {
String apiKey = getApplicationMetaData("google.client-id");
String scopes = "oauth2:server:client_id:" + apiKey
+ ":api_scope:" + LOGIN_SCOPES;
Bundle appActivities = new Bundle();
appActivities.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES,
"http://schema.org/AddAction");
String code = null;
try {
code = GoogleAuthUtil.getToken(getBaseContext(),
getPlusClient().getAccountName(), scopes, appActivities);
} catch (IOException e) {
Toast.makeText(getBaseContext(), R.string.error_network, Toast.LENGTH_LONG).show();
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), AUTH_CODE_REQUEST_CODE);
} catch (GoogleAuthException e) {
Log.e(TAG, "Google auth exception: ", e);
} catch (Exception e) {
throw new RuntimeException(e);
}
return code;
}
}
I have taken the code directly from the Developer Page. Though the docs don't clarify about many of the parameters, I think I have it correctly.
I have triple checked the apiKey and the getPlusClient().getAccountName() contents, they're correct. And I made sure the application and the server are in the same project on the API console.
No idea what else I could be doing wrong.
I have found the problem: The build.gradle file had a slightly (typoed) different valued for applicationId than what was set in the API-Console.
Though some simple error message in this case would have been great.
I have a Problem with commons-net FTPClient. If I download a file from my ftp server wirth retrieveFileStream() it works, but I get the result '150 Opening BINARY mode data connection for ...'. If I call noop() I get '226 Transfer complete' as result. For every following operation I get the result of the prvious operation.
I found out, that FTPClient reads results until end of line, if there are two result lines (as after retrieveFileStream()), I get the second one after the next command. I did a workaround by overriding FTPClient.retrieveFileStream() like this:
public static void main(String[] args){
try {
MyFTPClient ftpClient = new MyFTPClient();
try {
ftpClient.connect(ftphost, 21);
if(!ftpClient.login( ftpuser, ftppassword )){
throw new RuntimeException(ftpClient.getReplyString());
}
if(!ftpClient.changeWorkingDirectory("in")){
throw new RuntimeException(ftpClient.getReplyString());
}
FTPFile[] files = ftpClient.listFiles();
for(FTPFile file: files){
if(file.getName().startsWith(FILENAME) && (file.getType() == FTPFile.FILE_TYPE)){
InputStream in = ftpClient.retrieveFileStream(file.getName());
CsvFile csvFile = new CsvFile(in, "ISO-8859-1", ';', "yyyyMMdd", "#.00", Locale.US, false);
in.close();
in = null;
System.out.println(ftpClient.getReplyString());
System.out.println(ftpClient.readLine());
System.out.println(ftpClient.rnfr(file.getName()));
System.out.println(ftpClient.getReplyString());
System.out.println(ftpClient.rnto("x" + file.getName()));
System.out.println(ftpClient.getReplyString());
}
}
if(!ftpClient.logout()){
throw new RuntimeException(ftpClient.getReplyString());
}
} finally {
ftpClient.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static class MyFTPClient extends FTPClient{
public String readLine(){
try {
__getReplyNoReport();
} catch (IOException e) {
}
return getReplyString();
}
}
The call of the method readLine() gets me the additional Line of result.
But is this a bug of FTPClient or is it a problem of my ftp-server? The Problem of that workaround is, that the method blocks, if there is only one line of response.
Thanx for your help
Stephan
Sometimes it helps, reading the manual. A call of completePendingCommand() works
I was unable to find something similar to my application so I thought I would ask a new question. I am new to developing android (and java in general) but have some prior programming experience in C and Visual Basic. I am using a JPEG TTL Camera (Link Sprite LS Y201) and taking a picture to send from a TCP server to an android client device. On the client side, I am using an Async task to continuously get the data from the socket. So far, I have been able to get some bytes and store them in an array. Here are my questions:
1. The amount of data coming in from the socket is unknown. How to account for that?
2. How to check if all the data was read? The JPEG image data starts at hex value 0xFFD8 and ending value is 0xFFD9.
3. How to update this data to an imageview?
Thank you as well for taking the time to look this over. I really appreciate any help I can get!
The code I currently have is below:
// ----------------------- THE NETWORK TASK - begin ----------------------------
public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
Socket nsocket; //Network Socket
InputStream nis; //Network Input Stream
OutputStream nos; //Network Output Stream
BufferedReader inFromServer;//Buffered reader to store the incoming bytes
#Override
protected void onPreExecute() {
//change the connection status to "connected" when the task is started
changeConnectionStatus(true);
}
#Override
protected Boolean doInBackground(Void... params) { //This runs on a different thread
boolean result = false;
try {
//create a new socket instance
SocketAddress sockaddr = new InetSocketAddress("192.168.1.115",5050);
nsocket = new Socket();
nsocket.connect(sockaddr, 5000);//connect and set a 10 second connection timeout
if (nsocket.isConnected()) {//when connected
nis = nsocket.getInputStream();//get input
nos = nsocket.getOutputStream();//and output stream from the socket
BufferedInputStream inFromServer = new BufferedInputStream(nis);//"attach the inputstreamreader"
while(true){//while connected
ByteArrayBuffer baf = new ByteArrayBuffer(256);
int msgFromServer = 0;
while((msgFromServer = inFromServer.read()) != -1){;//read the lines coming from the socket
baf.append((byte) msgFromServer);
byte[] ImageArray = baf.toByteArray();
publishProgress(ImageArray);//update the publishProgress
}
}
}
//catch exceptions
} catch (IOException e) {
e.printStackTrace();
result = true;
} catch (Exception e) {
e.printStackTrace();
result = true;
} finally {
closeSocket();
}
return result;
}
//Method closes the socket
public void closeSocket(){
try {
nis.close();
nos.close();
nsocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//Method tries to send Strings over the socket connection
public void SendDataToNetwork(String cmd) { //You run this from the main thread.
try {
if (nsocket.isConnected()) {
nos.write(cmd.getBytes());
nos.flush();
} else {
outputText("SendDataToNetwork: Cannot send message. Socket is closed");
}
} catch (Exception e) {
outputText("SendDataToNetwork: Message send failed. Caught an exception");
}
}
//Methods is called every time a new byte is received from the socket connection
#Override
protected void onProgressUpdate(byte[]... values) {
if (values.length > 0) {//if the received data is at least one byte
if(values[85]== 255 ){//Start of image is at the 85th byte
///This is where I get lost. How to start updating imageview with JPEG bytes?
}
}
}
//Method is called when task is cancelled
#Override
protected void onCancelled() {
changeConnectionStatus(false);//change the connection to "disconnected"
}
//Method is called after taskexecution
#Override
protected void onPostExecute(Boolean result) {
if (result) {
outputText("onPostExecute: Completed with an Error.");
} else {
outputText("onPostExecute: Completed.");
}
changeConnectionStatus(false);//change connectionstaus to disconnected
}
}
// ----------------------- THE NETWORK TASK - end ----------------------------
On the server side, before sending each image, you could send an integer with the size of the image you're abut to transfer.
The available() function can be used for that. inFromServer.available() == 0 will tell you whether all data was read.
The following code will do it:
byte[] ImageArray = baf.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(ImageArray, 0, ImageArray.length);
imageView.setImageBitmap(bitmap);
Hope you find this useful! Good luck!
I am trying to make a monitoring application for a FTP server using FTP4J(referred to as client in the code example).
It connects to a FTP, logs in, creates a file locally, uploads file, downloads file, validates the files are the same, cleans up files on ftp and locally and disconnects.
All this is already made but my question is how do I best log what has happened and break when an error is detected?
The simple solution I could think of was to make a Boolean that shows if previous steps where successful and only do next step if they where.
StringBuilder sb = new StringBuilder();
boolean noError = true;
// Connect to FTP
try {
client.connect(hostname, port);
} catch (Exception e) {
noError = false;
sb.append("failed to connect<br>");
}
//Logging in to FTP
if(noError) {
try {
client.login(username, password);
} catch (Exception e) {
noError = false;
sb.append("failed to login<br>");
}
}
...
// Close connection
if(client.isConnected()) {
try {
client.disconnect(true);
} catch (Exception e) {
sb.append("failed to disconnect<br>");
}
}
another solution I could think of was nested try/catch but that looked even worse, is there a better way of doing this?
The solution is simple: don't catch the exception. As soon as an exception is thrown and is not caught, the whole process will stop. Or catch it but transform it into your own exception with the appropriate error message, and throw this exception.
Side note: you should use a boolean and not a Boolean to store a non-nullable boolean value.
StringBuilder sb = new StringBuilder();
Boolean noError = true;
// Connect to FTP
try {
client.connect(hostname, port);
client.login(username, password);
} catch (ConnectException ce) {
sb.append("Couldn't connect: ");
sb.append(ce.getMessage);
} catch (LoginException le) {
sb.append("Couldn't login: ");
sb.append(le.getMessage);
} finally {
if(client.isConnected()) {
try {
client.disconnect(true);
} catch (Exception e) {
sb.append("failed to disconnect<br>");
}
}