Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

Network file transfer

Thread view: 
Phillip D Ferguson - 23 Nov 2005 17:07 GMT
Hello,

i am relatively new to java, but i have a large amount of experience in C++
so the transition hasn't been too bad.
I am currently trying to build an application bit by bit so i am learning as
much as i can.
In the end i want an application that transfers XML files (via and HTTP
which will be good for debugging), but for the moment i am trying to build
one that just sends any file.

I have set up the appropriate code on each machine, sending a file from a
client to a server. However i am having problems with sockets.
I can send the file successfully but i would like the server to return some
acknowledgement, then i can figure out how to send another file etc.
I have tried sending a string but it doesn't work... can someone help?
Eventually i would like to send multiple files sequentially so i do need
some sort of acknowledgement even thought i am using tcp.
Im also having trouble with the naming of a file. If i send a file from the
client and want to save the file anywhere on the server, i need the file
name from the client. Can i extract it from the input stream or do i need to
request it separately?

My code for both sections is below:

Client code
-------------------------------------------------------------------------------------------------------
import java.io.*;
import java.net.*;

public class TCPClientfile
{

public static void main(String[] args) throws Exception
{

       Socket clientSocket = new Socket(host address and port);

       OutputStream dataOutput = clientSocket.getOutputStream();
       File inputFile = new File("readme_eclipse.html"); // example file to
send
       FileInputStream in = new FileInputStream(inputFile);

       byte[] buffer = new byte[2048];
       int numread;

       while ((numread = in.read(buffer))>=0)
        {
        dataOutput.write(buffer,0,numread);
        System.out.println("sending..." +numread); // console confirmation
of transfer
        }
      // if i de-comment the next section things dont work

     /*  BufferedReader inFromServer  =new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));

       modifiedSentence = inFromServer.readLine();

       System.out.println("FROM SERVER: " + modifiedSentence);
       */
       inFromServer.close();
       in.close();
       dataOutput.close();
       clientSocket.close();
   }
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Server code

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

import java.io.*;
import java.net.*;
public class TCPServerfile
{

public static void main(String[] args) throws Exception
{

      ServerSocket welcomeSocket = new ServerSocket(port number);
      System.out.println("listening");

           Socket connectionSocket = welcomeSocket.accept();
           System.out.println("socket accepted");
           InputStream dataInput = connectionSocket.getInputStream();

           File outputfile = new File ("readme_eclipse2.html"); // renamed
file from client, but how to get the original name?
           FileOutputStream out = new FileOutputStream(outputfile);

           byte[] buffer = new byte[2048];
           int numbread;

           while((numbread = dataInput.read(buffer))>=0)
             {
              out.write(buffer, 0, numbread);
              System.out.println("Receiving..." + numbread);
             }
           // code will hang here if i try to send string as commented
below

          /* DataOutputStream  outToClient = new
DataOutputStream(connectionSocket.getOutputStream());

           outToClient.writeBytes(Response);
           System.out.println(Response);
           */
           outToClient.close();
           out.close();
           dataInput.close();
           connectionSocket.close();
           welcomeSocket.close();

}
}
-------------------------------------------------------------------------------------------------------------------------------------

Can anyone offer me any corrections, advice.... good texts to read that
would help me at all?

Cheers!!

Phillip Ferguson

MEng student strathclyde university
Roedy Green - 23 Nov 2005 17:29 GMT
On Wed, 23 Nov 2005 17:07:15 GMT, "Phillip D Ferguson"
<fergy27@ntlworld.com> wrote, quoted or indirectly quoted someone who
said :

>I have set up the appropriate code on each machine, sending a file from a
>client to a server. However i am having problems with sockets.

All do you do is send a string of bytes, then, the receiver on getting
them all and saving them safely away, can write  single byte back into
the stream 0 or 1.  The other end on finishing the send, does a read
and waits for the byte to arrive, and when it does closes the socket.

You don't even need multiple threads.

http://mindprod.com/applets/fileio.html
for sample code.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Phillip D Ferguson - 23 Nov 2005 18:06 GMT
I was just testing both sides on two machines. I have not used any
multi-threading (yet).
My complication was dealing with the current stream which has just sent a
file, and configure it to send the acknowledgment.
Do i need a new stream/socket?

What you are saying is after i have received my file, i close that socket,
then open another to send a string to say the file has been received?

Is this correct?

thanks

Phillip

> On Wed, 23 Nov 2005 17:07:15 GMT, "Phillip D Ferguson"
> <fergy27@ntlworld.com> wrote, quoted or indirectly quoted someone who
[quoted text clipped - 12 lines]
> http://mindprod.com/applets/fileio.html
> for sample code.
Roedy Green - 23 Nov 2005 21:30 GMT
On Wed, 23 Nov 2005 18:06:45 GMT, "Phillip D Ferguson"
<fergy27@ntlworld.com> wrote, quoted or indirectly quoted someone who
said :

>Do i need a new stream/socket?

A socket comes with two streams one for input and one for output.

Again, please see http://mindprod.com/applets/fileio.html
for sample code.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

iksrazal@gmail.com - 23 Nov 2005 18:05 GMT
> Hello,
>
[quoted text clipped - 5 lines]
> which will be good for debugging), but for the moment i am trying to build
> one that just sends any file.

One simple and popular way to do this is via a class called HTTPClient
from jakarta commons, and any servlet. Just recieve the xml file as a
String. I can give more details if you'd like, or just use google.

HTH,
iksrazal
http://www.braziloutsource.com/
adamspe@gmail.com - 23 Nov 2005 20:07 GMT
Unless you really want to roll your own server and if you want to do it
via HTTP in the end then why not simply go that route (maybe write a
simple servlet that consumes the XML on the server).

The client could do something very simple like:

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL
import java.net.HttpURLConnection;

...
File xmlToSend = new File ( "/path/to/my.xml" );
if ( !xmlToSend.exists () ) ; // error
URL u = new URL ( "http://host/App/servlet/Consumer" ); // or whatever
HttpURLConnection connection = (HttpURLConnection)u.openConnection();
// need credentials or something?
// connection.setRequestProperty ( "Authorization", "Basic ...." );
connection.setRequestMethod ( "POST" );
connection.setDoOutput ( true );
connection.setRequestProperty ( "Content-Type", "text/xml" );
connection.setRequestProperty ( "Content-Length", ""+xmlToSend.length()
):
connection.setRequestProperty ( "Content-Disposition", "attachment;
filename=\"" + xmlToSend.getName() + "\"" );
// possibly not the most efficient way to stream, maybe use java.nio
InputStream in = new FileInputStream ( xmlToSend );
OutputStream out = connection.getOutputStream();
byte [] buf = new byte[4048];
int rd;
while ( (rd = in.read(buf)) != -1 )
 out.write ( buf, 0, rd );
in.close();
out.close();
if ( connection.getResponseCode() != 200 ) ; // something went wrong.
zero - 23 Nov 2005 20:37 GMT
> Hello,
>
[quoted text clipped - 19 lines]
>
> My code for both sections is below:

<snip>

I'm not sure what the "Response" is in your code, or why you're using a
DataOutputStream.  Have you tried something like this:

OutputStream out = connection.getOutputStream();

String data = "SERVER>>>FILE OK";

out.write(data.getBytes(), 0, data.length());
out.flush();
Phillip D Ferguson - 23 Nov 2005 22:58 GMT
Cheers for all the input guys its very much appreciated!!!

The utility Roedy mentions is all good, but its doesn't answer my query. Can
i leave the current socket open to send a string back to the client?
Zero might have the answer with the code below.... i'll be back with the
answer in 5 min.

Adam / iksrazal,

as much as i would love to just begin writing my own Http server but i just
don't have the knowledge at this time.
The spec at the moment is to send xml files from a (mobile) client, which is
full of data samples. The server then confirms it has the file, then acts as
a proxy to shunt the xml files to further client machines which will display
the data samples.
In the end i will want to write what you suggest but i feel i don't have the
knowledge or the resources to do it. Do you have any recommendations on
going down that road?
At the moment i need to learn more than anything, so just writing a
client/server setup which sends files is great. I then intend to go into XML
and the proxy setup on the other side.

thanks again!

Phill

>> Hello,
>>
[quoted text clipped - 31 lines]
> out.write(data.getBytes(), 0, data.length());
> out.flush();
Roedy Green - 23 Nov 2005 23:21 GMT
On Wed, 23 Nov 2005 22:58:17 GMT, "Phillip D Ferguson"
<fergy27@ntlworld.com> wrote, quoted or indirectly quoted someone who
said :

>The utility Roedy mentions is all good, but its doesn't answer my query. Can
>i leave the current socket open to send a string back to the client?
>Zero might have the answer with the code below.... i'll be back with the
>answer in 5 min.

you simply open both the OutputStream and InputStream on the same
socket.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

frankgerlach@gmail.com - 23 Nov 2005 23:23 GMT
You should design a formal protocol (or a "language") for you
client-server communications. From your code I am missing a length
parameter, which must be sent BEFORE the file. Only then the server can
determine whether everything has been read and can then send the
acknowledgment to the client.
The protocol should be like this:
Client to Server:
<SIZE><FILECONTENTS>
Server to Client:
<ACKNOWLEDGE>
As soon as you application grows more complex, you will be better off
with a well-defined protocol.
Also, do not forget to flush() your output streams as soon as you
expect the other side to sent some data. Your server code seems to
read() infinitely, because you do not check whether you have read SIZE
bytes.
Phillip D Ferguson - 24 Nov 2005 00:03 GMT
From earlier for zero... response was a string that was sent to the client
to confirm the server has received the file.

The server code reads until and end of file is found when the dataInput.read
returns a -1.
Then i know i have finished reading the file.

The problem is that after the while loop on the server terminates i cannot
add any code that allows me to send via the same socket connection, or else
it hangs. Otherwise the code exits nicely enough.
now the server reads:
-------------------------------------------------------
public static void main(String[] args) throws Exception
{

      ServerSocket welcomeSocket = new ServerSocket(6789);
      System.out.println("listening");

                Socket connectionSocket = welcomeSocket.accept();
           System.out.println("socket accepted");
           InputStream dataInput = connectionSocket.getInputStream();

           File outputfile = new File ("readme_eclipse2.html");
           FileOutputStream out = new FileOutputStream(outputfile);

           byte[] buffer = new byte[2048];
           int numbread;

           while((numbread = dataInput.read(buffer))>=0)
             {
              out.write(buffer, 0, numbread);
              System.out.println("Receiving..." + numbread);
             }
           System.out.println(numbread);
           System.out.println("whileloop completed");

           out.close();

           OutputStream  outToClient = connectionSocket.getOutputStream();

         String Response = outputfile.getName() + " has been received";

         outToClient.write(Response.getBytes(),0,Response.length());

         outToClient.flush();

             connectionSocket.close();
           welcomeSocket.close();

     }
-------------------------------------------------------

and the client
-------------------------------------------------
public static void main(String[] args) throws Exception
{
             String modifiedSentence;

       Socket clientSocket = new Socket(host and port);

       OutputStream dataOutput = clientSocket.getOutputStream();
       File inputFile = new File("readme_eclipse.html");
       FileInputStream in = new FileInputStream(inputFile);

       byte[] buffer = new byte[2048];
       int numread;

       while ((numread = in.read(buffer))>=0)
        {
        dataOutput.write(buffer,0,numread);
        System.out.println("sending..." +numread); // this lets me know
when everything is done
        }

       dataOutput.flush();

       BufferedReader inFromServer = new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()));

       modifiedSentence = inFromServer.readLine();

       System.out.println("FROM SERVER: " + modifiedSentence);

             clientSocket.close();
   }

-----------------------------------------------------------------------------------------

i'm really tearing my hair out on this one..... and i know its done to
practise... :-(

thanks for the input
Phill

> You should design a formal protocol (or a "language") for you
> client-server communications. From your code I am missing a length
[quoted text clipped - 12 lines]
> read() infinitely, because you do not check whether you have read SIZE
> bytes.
frankgerlach@gmail.com - 24 Nov 2005 09:46 GMT
See my comments in your code :

public static void main(String[] args) throws Exception
{

      ServerSocket welcomeSocket = new ServerSocket(6789);
      System.out.println("listening");

                Socket connectionSocket = welcomeSocket.accept();
           System.out.println("socket accepted");
           InputStream dataInput = connectionSocket.getInputStream();

           File outputfile = new File ("readme_eclipse2.html");
           FileOutputStream out = new FileOutputStream(outputfile);

           byte[] buffer = new byte[2048];
           int numbread;
           //at this point you MUST transmit/read the length of the
file
           //because you MUST terminate your loop after the file has
been
           //completely read. Currently this is an ENDLESS loop !!
           while((numbread = dataInput.read(buffer))>=0)
             {
              out.write(buffer, 0, numbread);
              System.out.println("Receiving..." + numbread);
             }
            //Your loop should look like this:
            // int fileSize=<READ FILE SIZE FROM INPUTSREAM>
            // int readUpToNow=0;
            // do{
            //     int
validBytes=dataInput.read(buffer,0,buffer.length);
            //     out.write(buffer, 0, validBytes);
            //     readUpToNow+=validBytes;
            // }while(readUpToNow<fileSize);

           System.out.println(numbread);
           System.out.println("whileloop completed");

           out.close();

           OutputStream  outToClient =
connectionSocket.getOutputStream();

         String Response = outputfile.getName() + " has been
received";

         outToClient.write(Response.getBytes(),0,Response.length());

         outToClient.flush();

             connectionSocket.close();
           welcomeSocket.close();

     }
adamspe@gmail.com - 29 Nov 2005 16:23 GMT
My thought here was not that you write an HTTP Server.  There's no need
to do such a thing since there are many freely available ones out there
to meet that need.  you could simply run Tomcat with HTTP enabled or
Apache+tomcat or pick your favorite webserver servlet engine combo and
write a tiny servlet to plug in there to consume your XML.  All the
protocol details, authentication, etc. will be handled by the server
and the java.net classes on your client side, no need to -really-
understand all the specifics of the underlying protocol, just small
bits of code on both sides of the wire.
Thomas G. Marshall - 29 Nov 2005 20:03 GMT
adamspe@gmail.com said something like:
> My thought here was not that you write an HTTP Server.  There's no
> need to do such a thing since there are many freely available ones
[quoted text clipped - 5 lines]
> no need to -really- understand all the specifics of the underlying
> protocol, just small bits of code on both sides of the wire.

Please supply a quote.
adamspe@gmail.com - 30 Nov 2005 16:44 GMT
Sorry.

>> Adam / iksrazal,
>>
[quoted text clipped - 20 lines]
> understand all the specifics of the underlying protocol, just small
> bits of code on both sides of the wire.

My point was that existing software and APIs exist to deal with both
sides of the wire via HTTP that could be re-used without the need to
invent a protocol and write the client and server.
Phillip D Ferguson - 01 Dec 2005 21:44 GMT
Adam,

your comments are much appreciated!!! I began to realise that this is the
easiest approach, as i really wish i had the time to go into java in that
much details as to code my own http server, but you are not the only one to
suggest that i use tomcat etc to do this.
How simple is it to write myself a servlet to deal with my xml files?  I
have yet to go into XML in detail with the DOM and SAX availabilities.

Cheers

Phill

> Sorry.
>
[quoted text clipped - 32 lines]
> sides of the wire via HTTP that could be re-used without the need to
> invent a protocol and write the client and server.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.