p2p

Hi

i am currently developping a p2p program like emule/gnutella … for a school project
I am using a server/client tcp/ip protocol to send data between clients
Sending strings and giving commands works fine but i cant seem to send files.
Is there any1 here who could post a small example code of sever/client sending a file

thanks

For sending files you can’t just send the File object, unlike with most other objects since the File object is just an address, not the actual file’s bytes.

See the Java Tutorial for info, but here’s the rounda-about code that should give you an idea of how it works (but definitely won’t compile):

File aFile = new File(“C:/etc.txt”);
// What you need to do is read the file in as a byte[] array, so
BufferedInputStream in = new BufferedInputStream(new FileInputStream(aFile));
byte[] bytes = null;
in.readBytes(bytes); // this line is not right, I think you have to loop thru doing reads until you get -1 returned…
//now that we have the file’s bytes, just send the bytes out over a Socket or whatever by getting its OutputStream
someSocket.getOutputStream().write(bytes);

To recieve the bytes on the other computer,

InputStream in = someOtherSocket.getInputStream();
byte[] bytes = new byte[in.available()];
someOtherSocket.read(bytes);
// now that we have the bytes, write them to the drive.
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(“C:/etc2.txt”)));
out.write(bytes);

This code is probably completely wrong, its just off the top of my head. Definitely consult the Java Tutorial, they explain it & give examples. At least my code shows that writing/reading a file’s bytes & saving them to the computer is harder than writing/reading objects, but I’m sure you’re up to the job :wink:

Keith

Well i kinda allready do something simular to your things here

I read the “packages” of a file at server side (like byte[1024])
then i transfor those to an object which i wrie to client with an ObjectOutputStream

at client side i read the object with a ObjectInputStream and then get the byte[] packages from it
which i write to the file then
it works but i only get a speed of 6 kb/s or even slower
this is realy low i think.

Make sure you buffer everything, instead of writing/reading bytes one at a time. See the Buffered I/O streams.

Keith

this is an overview of streamsi use

to read file: FileInputStream, write: FileOutputStream
to send data: ObjectOutputStream, receive/read: ObjectInputStream

should i read the file continious (thread) and stack the objects?
The current method involves reading the next part when needed

and similar for writing the file should i stack some object to a number of 100 and then write those 100 at once?
Current method is writing an object when receiving.

I am not sure why you are using objectoutput streams at all…

I would use a dataoutputstream to firstly write an integer describing the block being sent then send the byte block.

i.e.


DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
FileInputStream fis=new FileInptuStream(****file to send ****);
DataInputStream dis=new DataInputStream(fis);
byte[] block=new byte[1024];
int blocknumber=****a valid block number***

try
{
    try
    {
        dis.readFully(block);
    } catch (EOFException e)
    {
    }
    
    dos.writeInt(blocknumber);
    dos.write(block);
}
catch (IOException e)
{
    e.printStackTrace();
}


obviously the client will be listening for the block number and then for the block.

Well i sort got it going well but now the problem is that when i send files bigger then 60 mb i get an error

exception in thread: java heap space exceeded
How can he exceed this when i use 2 buffers (arraylist) of 100 packes of 64kb so *6.4mb = 13mb the buffer should be more then big enough

well, if you think that the buffers are causing you to run out of memory then I would suggest not using an in-memory buffer.

assuming that this is on the recieving end simply use a random access file and write the block to the appropriate position in the file.

Actually i dont see the need to have a buffer of blocks at all in memory… On the client side simply remember the indecies of the blocks you have recieved and on the server side there is no need to remember anything.

I used buffers for the simple reason that the file you wonna send is continiously read so you dont have to start reading a part when you need it, you have allready it so it should speed up things

… and uses a lot of memory (as file size). Best thing I can think of is read a part, then start to send it and when you’re almost over with sending that part read next part of file and so on…