Link to home
Start Free TrialLog in
Avatar of J_Seaman
J_Seaman

asked on

FTP J2ME


I'm struggling with this one so any ideas at all are welcome.

I've written some J2ME code for uploading files to an ftp server. I do all the logging in, navigating directories etc then try to send my data. I've been running this on a couple of free ftp servers on the net with no probs. The live system has now been set up and I can't send data. I go through all the normal steps but it fails at the last hurdle:

TYPE I -> Changes to binary mode correctly
PASV -> executed and returns the new connection details for transfer
STOR -> also executes and tells me it is ready to receive a file (Response 125)

I then send the data, close the output stream to the server and wait for a response ... nothing! The server doesn't give me a 226 transfer complete for some reason. If I don't look for this and try to make another file transfer, I get an error response that the server can't complete the request in its current state, it says to use ABOR to cancel the operation (Which I presume is the file transfer??).

To complicate matters, using FTP at the dos level works fine and gets 226 transfer complete.

What am I doing wrong which makes this specific server not work?! Am I right to think that you complete the file transfer by just closing the output stream?

Thanks

James.
Avatar of mmuruganandam
mmuruganandam
Flag of United States of America image

Post your upload part of the code.
Avatar of J_Seaman
J_Seaman

ASKER

SendToFTP is a function which sends a string to the ftp sever over the control socket. GetFTPResponse retrieves text from the ftp server until a completion response (nnn text response returned) is found or timeout occurs

                DataSocketStream=TransferSocket.openOutputStream();
                SendToFTP ("STOR /" + MainMIDlet.Settings[MainMIDlet.SERIAL_NUMBER] + "/" + DestinationFileName + "\r\n");

                Response = GetFTPResponse();
                if (Response.length()>3 && Response.charAt(0)>= '1' && Response.charAt(0)<='3')
                {
                    InputFile.open (FileName);
                    //Get the size of the file to be sent
                    FileLength = InputFile.length();
                    //Create a buffer to hold the number of bytes required
                    FileBuffer = new byte[FileLength];
                    InputFile.read(FileBuffer, 0, FileLength);
                    InputFile.close();
                    InputFile=null;

                    System.out.println ("Sending file.");
                    DataSocketStream.write(FileBuffer, 0, FileLength);
                    System.out.println ("File sent. Closing down streams.");
                    FileBuffer=null;
                   
                    try
                    {
                        DataSocketStream.close();
                        TransferSocket.close();

                        Response = GetFTPResponse();

                        DataSocketStream=null;
                        TransferSocket=null;

                        if (Response.length()>3 && Response.charAt(0)>= '1' && Response.charAt(0)<='3')
                        {
                            System.out.println ("Streams closed.");
                            System.out.println ("File sent OK.");
                            return true;
                        }
                        else
                        {
                            System.out.println ("FAILED!");
                        }


The code works on all other ftp servers I have tried, was wondering if there's anything special you are supposed to do on completion of a data send that these other servers were detecting cleverly.

I found some code for ftp server receiving a STOR command and it seems that it reads data until there isn't any left then closes the file which seems logical. I just can't seem to figure out why I'm getting no response
DataSocketStream >> is it a buffered stream

If so, are you flushing it.


Flushing it after the data send? If so, before the stream is closed?
that is right

DataSocketStream.flush();



Does nothing :o(
TransferSocket.close();
Response = GetFTPResponse();


Can you swap these two lines.  I was just thinking about different possibilities as I don't have your full code.


If I don't wait for the ftp response then try another send, the error message is :

"451 This command is not valid in the current state. Use ABOR to abort the current operation."

I don't know if that helps you understand what the FTP server is doing but I'm guessing it still thinks there is an open data stream doing the file transfer. Is there some way to force the ftp server to realise the stream has shut? ie am I not doing a graceful shut down by simply sending then terminating the stream? (even witha flush)

I'll try swapping those lines - I'll give you as much code as I can.

I've actually removed the closure of the socket to see if that will let the response come in but it doesn't. Shouldn't really either because the response is coming off the control stream and I'm closing the data stream.
Are you making synchronized calls or your programs running in threads.  That means in asynchronous.  

Swapping those lines didn't do anything either, still getting no response at the end.

Any shared data is synchronised, don't think it's that kind of an issue though, do you?

I successfully execute a USER, PASSWORD, TYPE I, PASV, STOR with no difficulty. It's always the same problem in the same place, I would've thought thread synchs would be a bit more erratic.
can you post

DataSocketStream
TransferSocket


        OutputStream DataSocketStream=null;

Local to the function given previously and initialised based on TransferSocket.

    StreamConnection TransferSocket=null;

Global variable setup in response to the PASV ftp command.  PASV gets a response of:

"SERVER : 227 Entering Passive Mode (194,202,64,72,40,127)"

I take the first four octets returned from PASV (194.202,64.72), then appends : Port where Port is the next octet * 256 + the final octet.

Hope that's enough.
in the PASV mode  you might be calling STOR <filename>.  I am really wondering where it is missing...

In order to figure out any problem in your JVM, can you use FTPClient.class to transfer a file.
If that works, we have to really debug this problem.


Returned from the server :
227 Entering Passive Mode (194,202,64,72,66,118)

Socket opened :
socket://194.202.64.72:17014

I also output the DataSocketStream variable to screen before and after I opened the socket, values were :

Datasocket was : null
Datasocket now : com.sun.cldc.io.j2me.socket.PrivateOutputStream@d590dbc

So the socket seems to have been set up correctly

"in the PASV mode  you might be calling STOR <filename>.  I am really wondering where it is missing..."
Eh?! I am calling STOR after PASV, is this incorrect?

"can you use FTPClient.class to transfer a file"
I don't know, can I - it's J2ME and MIDP I'm u sing and I'm not familiar with it. I know it's a cut down versino of the JVM but I don't think I've got the ftp class
what is the mode in which you are pushing the data?

I mean binary or ascii...

Binary but tried ascii
Sorry James... There would be some minor issue.  It would be too tough to debug by assumptions.
Let the question be open for some experts suggestion....

OK, cheers for the help though - nice to have someone else to look at the problem.

All the best

James.

OK, cheers for the help though - nice to have someone else to look at the problem.

All the best

James.
Anyone else?
James,

Why don't you increase the points.  That may help others to have a look at it.

Done

Will more points get any attention?!

Can you upload the code somewhere.  Let me have a look.  I have even wrote a FTP Client.   That works with every thing.   But that is using FTPClient.class in J2SE


Regards,
Muruga

I'm afraid I won't be able to do that - sorry! I'll give as much as I can but you know how it is. Have you got an idea?
I am really not!  Assumptions won't solve the problem!

That is the reason why I asked for code.  I can understand the difficulties in publishing the code for public.

Can you check whether you have a FTPClient.class in the RT.JAR of J2ME.

Regards,
Muruga

Yeah, I know what you mean - I'm trying to give you as much info as possible but it's nothing like seeing the actual code.

I've had a quick look through the RT.jar file and one of them has references to ftpclient (j2sdk1.4.1_02\lib) and one doesn't (program files\java\j2re1.4.1_02\lib)

I think it supports http but not ftp by default
do you mean FTPClient.class is existed in one of the rt.jar

One of the rt.jar files has references to it but I don't think it's in the spec of j2me ie i can't use it. I'm sure this problem lies in the server now but I just can't prove it yet - bangin head against brick wall
ASKER CERTIFIED SOLUTION
Avatar of mmuruganandam
mmuruganandam
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

HA!

FTP server firewall screwing everything up!! Wasn't me :o)

Muruga - you are potentially THE most persistent person I've come across on this groupand purely for your efforts I'm going to award you the points. Some people feel a bit iffy about that but I think you've worked on this enough to warrant them so there.

Thanks a lot

James.
Thanks James for you comments!

It is my great pleasure working with you.


Regards,
Muruga