» »

Kako pošiljanje datotek v JAVI.

Kako pošiljanje datotek v JAVI.

shock ::

Rad bi naredil program v javi ki pošilja datoteke prek interneta. Naredil bi server in Client, kjer Client pošilja serverju datoteke. A ima kdo kak kos programa kjer je to opisano? Dobrodošle so tudi samo smernice kako bi kaj naredil.

kopernik ::

Hmmm, server mora poslušati na določenem portu (npr. 7777), client pa potem odpira konekcije z objekti tipa URLConnection. Pošiljanje fajlov tudi ni problem - datoteko na clientu prebereš z FileInputStream-om in jo pošlješ preko konekcije na server, kjer jo zapišeš s FileOutputStream-om. Malce težje je le implementirati server, ker mora biti multithreaded, če hočeš, da lahko hkrati sprejme konekcije večih clientov. Osnovne koncepte client-server koncepta in branja/zapisovanja datotek si lahko pogledaš v kaki javanski knjigi (npr. Thinking in Java, ki je zastonj v html obliki).
Upam, da se že kaj spoznaš na Javo (vsaj stvari okrog kompajlanja classov in njihovega zaganjanja), ker se mi ne da razlagati. Aja, stvar sem stipkal na hitro, tako da so napake možne. Stestiraj in boš videl.

Client na kratko:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class Client
{
public static void main(String[] args) {
//ime datoteke, ki jo hoces poslati
String fileName = args[0];
//url serverja (npr. http://127.0.0.1:7777 , ce bos testiral
//clienta in server kar na istem racunalniku - tisti port 7777 nastavis na serverju).
String serverAddress = args[1];
//file bomo brali po 1K
byte[] buffer = new byte[1024];

//nalozi datoteko
FileInputStream in = null;
//ouput stream, v katerega bomo pisali prebrano datoteko
OutputStream out = null;
try {
//odpri konekcijo do serverja
URL url = new URL(serverAddress);
URLConnection connection = url.openConnection();

//preberi datoteko in pisi na stream v konekciji
in = new FileInputStream(args[0]);
out = connection.getOutputStream();
int size = 0;
while((size = in.read(buffer)) != -1) {
out.write(buffer);
}
} catch(MalformedURLException me) {
//napaka pri povezovanju na streznik
me.printStackTrace();
} catch(IOException e) {
//napaka pri branju/posiljanju datoteke
e.printStackTrace();
} finally {
try {
in.close();
out.close();
} catch(IOException ex) {
//lahko ignoriras
}
}
}
}




Server na kratko (potrebna sta vsaj dva razreda - da je koda bolj razclenjena)):


import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

public static void main(String[] args) throws IOException {
String serverPort = args[0];
//spremenljivka za lazje zapisovnje datotek.
int fileCount = 0;
//server poslusa na portu serverPort
ServerSocket server = new ServerSocket(Integer.parseInt(serverPort));
System.out.println("Server zagnan na vratih:\t" + serverPort);

//neskoncna zanka
while(true) {
Socket client = server.accept();
fileCount++;

//izpisemo nekaj podatkov o clientu
System.out.println("Nov client [" + client + "]");
FileFetch fetcher = new FileFetch();
fetcher.setClient(client);
fetcher.setFileNumber(fileCount);

//pozenemo thread, ki se bo posvetil trenutnemu clientu
new Thread(fetcher).start();
}
}
}


in še FileFetcher:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class FileFetch implements Runnable {
private Socket client = null;
private int fileNumber = -1;

public void run() {
String file = null;

if(fileNumber != -1) {
file = "file" + fileNumber;
InputStream in = null;
FileOutputStream out = null;

try {
//zapisovali bomo v datoteko (ce ze obstaja, jo prepisemo)
out = new FileOutputStream(file);
//beremo iz socketa
in = this.client.getInputStream();

byte[] buffer = new byte[1024];
int size = 0;

while((size = in.read(buffer)) != -1) {
out.write(buffer);
}

System.out.println("Datoteka " + file + "shranjena!");
} catch (FileNotFoundException e) {
//napaka pri kreiranju (odpiranju) datoteke
e.printStackTrace();
} catch (IOException e1) {
// vhodno-izhodna napaka
e1.printStackTrace();
} finally {
try {
in.close();
out.close();
} catch (Exception ex) {
//ignoriramo napako
}
}
}
}

/** Nastavi socket. */
public void setClient(Socket socket) {
client = socket;
}

/** Nastavi fileNumber. */
public void setFileNumber(int i) {
fileNumber = i;
}
}



lp

Zgodovina sprememb…

  • spremenil: kopernik ()

shock ::

kopernik: hvala za primer, sem še začetnik v Javi pa poskušam kaj naredit. Kako pa je to preverjenje prenos podatkov, če so podatki prav prišli skozi? Al to poskrbi že sam TCP/IP protokol? Pa še nekaj kaj če bi samo hotel določen del fajla posneti čez? Kaj tukaj slučajno uporabljam Random-ACcess File?

shock ::

Pa še nekaj me zanima, kako pa je s preobremenitvijo procesorja? To bi preobremenjeval procesor kot eMule in Co.?

kopernik ::

Jaz sem pokazal najlažjo pot. Če hočeš bolj low-level (branje TCP/IP headerjev, itd. ), potem moraš uporabiti druge classa iz JDK-ja. Nekaj podatkov sicer vsebuje že Socket, ki sem ga uporabil zgoraj.

Glede preverjanja podatkov in ostalih stvari pri samih protokolih : to je spet bolj low-level in Java sama vse naredi. Če pride do kake napake ti itak vrže Exception.

Random Access fileti : obstaja class RandomAccessFile, ki pa ga sam še nisem uporabljal. Zelo priporočam branje Java API, kjer so opisi za vse razrede iz JDK (kjer so razredi za praktično vsako stvar, ki jo želiš narediti). Je pa res, da je področij kar dosti in je potrebno ogromno časa, da obvladaš vsaj nekaj izmed njih.

preobremenitev procesorja? nimam pojma. Še nisem testiral. Pri velikem številu klientov (konekcij in threadov) bi se najbrž obremenjenost kar povečala. Lahko bi npr. omejil max. št. trenutno odprtih konekcij in s tem preprečil kakšen OutOfMemoryException. Ne vem, ekstremni pogoji so vedno problematični. Mislim pa, da nekaj sto konekcij ne bi smelo biti problematično (razen pri bandwidthu zaradi uploada). Ta primer, ki sem ga podal je res najbolj osnoven. Rabil bi vsaj še kako logiko za razvrščanje in čakanje klientov, itd.

lp

kopernik ::

aja, mimogrede, obstaja že en open.source projekt,

Limewire

ki je cel spisan v Javi (če te zanima bolj podrobno, kako je narejen file-sharing).

shock ::

kopernik: nekaj me zanima in kaj se zgodi če je promet prek interneta prepočasen?

while((size = in.read(buffer)) != -1) {
out.write(buffer);
}

potem bi prišlo do rezultata -1 pri (size = in.read(buffer)) ali kako je s tem?

shock ::

aja sem naredil en tak program server in client s pomočjo tvojega primera in sem opazil, da nastopa problem lih pri tej vrstici

while((size = in.read(buffer)) != -1) {
out.write(buffer);
}

Tukaj mi piše v fajl večkratno vsebino zarad te zanke, podatki skoz internet mi tečejo počasneje kot piše to na disk in npr. buffer se mi napolne šele po 4 ciklih while zanke

kopernik ::

Ne dela ti pravilno? hmm, čudno. Bom malce stestiral. Odgovorim ti jutri.

Pisanje v out pa pri počasnem internetu nima vpliva (razen, če gre za connection timeout, ko client ali server ni več dostopen), vsaj kar sem se jaz enkrat s tem igral. Je pa res, de sem ta primer stipkal bolj na hitro.

shock ::

Vem, da ni lahko samo malo poglej kako je s tistim delom na serverski strani, saj tista zanka je tako hitra da prepisuje v datoteko ponovno star bufer. Če hočeš ti pošljem na e-mail moje datoteke. Drugače sem stestiral iz dveh računal, ki so v mreži.

Zgodovina sprememb…

  • spremenil: shock ()

kopernik ::

poskusi še za vsak slučaj na clientu in na serverju zamenjati

out.write(buffer)

z

out.write(buffer, 0, size);

shock ::

ne gre vseen. Če hočeš ti pošljem fajle da bi videl kako veliko datoteko mi naredi ;)

kopernik ::

Meni to deluje. Poglej malo v Java API in uporabi kakšen drugačem Stream (npr. BufferedInputStream). Sorry, ampak nimam preveč časa za vse možne scenarije. Poglej malo na google(npr. "sending files over http in java") in pa že prej omenjeni limewire, kako se pošilja datoteke.

shock ::

Sem iskal po internetu pa sem naletel na naslednji primer

CODE FOR SERVER

import java.io.*;
import java.net.*;
public class ReadFile
{
public static void main(String[] args)
{
ServerSocket serverSocket = null;
Socket clientSocket;
try
{
serverSocket = new ServerSocket(2000);
}
catch (IOException e)
{
System.out.println("Couldn't listen to port 2000");
System.exit(1);
}
clientSocket = null;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
System.out.println("I/O exception in serverSocket.accept()");
}
try
{
File f = new File("ReadFile.java");
FileInputStream fis = new FileInputStream (f);
DataInputStream is = new DataInputStream(new
BufferedInputStream(clientSocket.getInputStream()));
OutputStream os = clientSocket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
String inp;
int fsize = fis.available();
System.out.println("Size is " + fsize);
dos.writeInt(fsize);
dos.flush();
is.readByte();
byte[] buf = new byte[3000];
while ((fis.read(buf)) != -1)
{
System.out.println("Sending");
os.write(buf);
os.flush();
is.readByte();
}
fis.close();
os.close();
is.close();
}
catch (IOException e)
{
System.err.println("I/O Exception");
}
}
}


CODE FOR CLIENT:

import java.lang.*;
import java.io.*;
import java.net.*;

public class GetFile
{
public static void main(String[] args)
{
Socket echoSocket = null;
DataOutputStream os = null;
InputStream is = null;
DataInputStream dis = null;
try
{
echoSocket = new Socket("206.78.144.21", 2000);
os = new DataOutputStream(echoSocket.getOutputStream());
is = echoSocket.getInputStream();
dis = new DataInputStream(echoSocket.getInputStream());
}
catch (UnknownHostException e)
{
System.err.println("Don't know host xxx.xxx.com");
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for host xxx.xx.com");
System.exit(1);
}
if (echoSocket != null && os != null && is != null)
{
System.out.println("Trying to receive data");
try
{
String inp;
File outputFile = new File("myReadFile.java");
FileOutputStream fos = new FileOutputStream(outputFile);
byte[] buff = new byte[3000];
int fSize;
int sizeRead = 0;
fSize = dis.readInt();
System.out.println ("Size of file is " + fSize);
os.writeByte('\n');
os.flush();
while ((is.read(buff)) != -1)
{
sizeRead += 3000;
if (sizeRead < fSize)
fos.write(buff);
else
{
byte[] buff1 = new byte[fSize - (sizeRead-3000)];
for (int i=0; i < (fSize -(sizeRead - 3000)); i++)
buff1 = buff;
fos.write(buff1);
}
os.writeByte('\n');
os.flush();
System.out.println("File copied");
break;
}
os.close();
is.close();
fos.close();
echoSocket.close();
}
catch (IOException e)
{
System.err.println("I/O failure");
}
}
}
}

Zdaj bi nekoga prosil, če bi poskusli naredit tole in če vam dela. Meni nikakor ne uspe poslat iz enga racunalnika v drugi racunalnik datoteko. Vedno pride do napake z I/O Exception.

pa še eno stvar bi prosil za razlago, kaj pomeni pri klientu ko pošlješ

os.writeByte('\n');
os.flush();

in server čaka na

is.readByte();

Hvala

kopernik ::

ta primer je, če prav vidim, glih kontra (torej download iz serverja in ne upload na server). Je pa kar čuden primer saj npr. client hkrati bere in piše. Ne vem,sporoči, če ti ga bo uspelo usposobiti.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[JAVA] HTTPS client

Oddelek: Programiranje
173058 (1788) peterv6i
»

Java skeniranje map in podmap

Oddelek: Programiranje
61072 (961) nightrage
»

[Java] Multi Client chat server

Oddelek: Programiranje
262354 (1625) javaMaster
»

[JAVA] zaustavitev niti (threadov)

Oddelek: Programiranje
223049 (3049) morbo
»

[java] Runtime.exec()

Oddelek: Programiranje
111812 (1685) borchi

Več podobnih tem