Odbieranie pliku w wielu wątkach

0

Witam,

Czy ktoś ma pomysł w jaki sposób zrealizować odbieranie pliku w chociażby 2 dwóch wątkach?
Plik jest przesyłany między socketami (aplikacja klient - serwer)

To co jest dla mnie problemem to głównie to, jak odróżnić do którego wątku powinien zostać skierowany dany pakiet .
Bo jeden wątek np odbiera plik od początku do połowy, a drugi reszte...

0

Wysłaj pakiety, w ktorych bedziesz okreslal w ktorym "strumieniu" jest to wysylane. Albo po prostu odbieraj na wielu portach jednoczesnie, co jest chyba najsensowniejsze.

0

Dawno temu, na zaliczenie jakiegos przedmiotu robiłem cos na kształt rozproszonego systemu plików. i miałem tam funkcjonalność, o która pytasz.
Wszystko rozbija się o to, żeby protokół komunikacyjny dawał możliwość pobierania fragmentów plików oraz informacji o wielkosci pliku.
a jak wyglądało:

  1. Klient pyta serwer o plik super_film.avi
  2. Server odpowiada, że ma plik i przesyła jakies szczegółowe informacje o tym pliku: wielkość, gdzie jest zlokalizowany
  3. Klient uruchamia kilka wątków pobierających, każdemu przekazuje zakres bajtów (od, do) jakie ma pobrac.
  4. Kazdy z watkow klienckich uruchamia połączenie z serwerem i prosi o przesłanie części pliku super_film.avi. Otrzymywane bajty zapisywane są do pliku super_film.avi.part${id_watka}
  5. Po zakończeniu transferu Klient scala pliki.

O to ci chodziło? czy może oczekiwałeś kawałki kodu?

0

Dzięki za podpowiedzi!

Wczoraj starałem się napisać to korzystając z jednego socket'a, ale niestety...

Zrobię tak jak napisałeś krzyzy, tzn po połączeniu się z serwerem udostępniającym plik, wymienię między nim, a klientem dane informacyjne o pliku, a następnie wystartuję wątki w których będę realizował połączenia z osobnymi socketami.

Aby móc wysyłać / odbierać część pliku (np od poczatku do polowy i od polowy do konca), zamierzam użyć klasy RandomAccessFile (nadaje się?:))

0

tak, nadaje sie.

0

Niestety jest mały problem.
Plik przesyłam w dwóch wątkach i pierwszy z nich, który startuje od początku ładnie przesyła mi połowę pliku (przesyłam JPEG i wyświetla się tylko połowa zdjęcia).
Niestety drugi, który startuje od połowy nie przesyła pliku poprawnie (jpeg wcale się nie wyświetla)...

Fragment wąteku wysyłającego:

RandomAccessFile raf = new RandomAccessFile(plik, "rw");

//start i stop to parametry przekazywane do watku
//jesli start rowna sie polowie to przesylamy druga czesc pliku
//ale trzeba pomniejszyc stop, ktory rowna sie wielkosc pliku
//aby poprawnie obliczyc "iloscBlokow" i "reszte"
if (start != 0) {
    stop = stop - start;
}
			
int iloscBlokow = stop / Config.getBLOK();
int reszta = stop % iloscBlokow;
int wczytane = 0;
	
byte[] plikBajty = new byte[Config.getBLOK()];
byte[] resztaBajty = new byte[reszta];
			
raf.seek(start);
for (int i = 0; i < iloscBlokow; i++) {
    wczytane = raf.read(plikBajty, 0, plikBajty.length);
    output.write(plikBajty, 0, wczytane);
    output.flush();
}
			
if (reszta != 0) {
    wczytane = raf.read(resztaBajty, 0, resztaBajty.length);
    output.write(resztaBajty, 0, wczytane);
    output.flush();
}

raf.close();

Fragment wątku odbierającego:

File plik = new File(Config.getNAZWA_KATALOGU()+Liczbalosowa+nazwaPliku);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(plik));

int odebrane = 0;
byte[] plikBajty = new byte[blok];
	
while (odebrane != -1) {
    odebrane = input.read(plikBajty, 0, plikBajty.length);

    if (odebrane != -1) {
        bos.write(plikBajty, 0, odebrane);
        bos.flush();
    }
}

bos.close();

Może ktoś ma pomysł czemu pierwsza część pliku przesyła się OK, a druga wcale :)

0

Czy jesteś pewien, że druga część sie nie wysyła. Z tego co mowisz to wnisek taki wyciągnąłeś na podstawie tego, że jpeg sie nie otwiera. A wziąłeś pod uwagę to, że jpeg swoj naglowek ma na początku pliku i bez tego nagłówka nie da się otworzyć pliku (w prosty sposób).

Najlepiej będzie jeśli spróbujesz złączyć otrzymane części w jeden plik i dopiero wtedy próbować otworzyć.

Do takich testów polecam użycie nie plików binarnych tylko tekstowych - łatwiej sie weryfikuje poprawność operacji.

0

OK, a w jaki sposób najlepiej złączyć plik w całość?

0

Windows:
copy /B plik1+plik2 razem /B

0

jemu chodzilo chyba o mergowanie z poziomu kodu javy.

a mozna to zrobic nastepujaco:

  1. Wszystkie watki zglosily informacje ze zakonczyly pobieranie
  2. Otwierasz plik super_film.avi do zapisu
  3. Dla kazdej pobranej cześci pliku (w odpowiedniej kolejnosci) otwierasz ją i przepisujesz do strumienia z p.2.
0

@krzyzy, Ty opisujesz rozwiązanie ostateczne. A ja myślę, że @szu ściągnął dwa kawałki obrazka i chce sprawdzić czy one razem tworzą obrazek. Polecenie copy (cat) jest do tego bardzo odpowiednie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1