Network file transfer

P

Phillip D Ferguson

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
 
R

Roedy Green

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.
 
I

iksrazal

Phillip D Ferguson escreveu:
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.

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/
 
P

Phillip D Ferguson

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
 
A

adamspe

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.
 
Z

zero

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:

<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();
 
P

Phillip D Ferguson

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
 
R

Roedy Green

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.
 
F

frankgerlach

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.
 
P

Phillip D Ferguson

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
 
F

frankgerlach

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();

}
 
A

adamspe

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.
 
T

Thomas G. Marshall

(e-mail address removed) 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
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.

Please supply a quote.
 
A

adamspe

Sorry.
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.

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.
 
P

Phillip D Ferguson

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top