Wątek przeniesiony 2024-03-11 18:37 z C/C++ przez Althorion.

Jaki rozmiar buforu do uploadu pliku na własny serwer?

0

Witam
Jak rozmiar buforu (chunks) w fetch() (JS) ustawiać żeby wszystko ładnie szło na serwer?

Obecnie ustawiam 4500 bajtów i używam rekurencji żeby to zapisać na dysku , 4500 to ok rozmiar?

0

Po co dzielić? (Żeby rządzić? ;) ) Najlepiej od razu całe dane. I tak dzielenie nic tutaj nie daje, a opóźnia i zwiększa liczbę negocjacji połączeń. Zanim nie pobierzesz całych danych, to i tak nie wykorzystasz części już pobranej. 13:37 :>

0
overcq napisał(a):

Po co dzielić? (Żeby rządzić? ;) ) Najlepiej od razu całe dane. I tak dzielenie nic tutaj nie daje, a opóźnia i zwiększa liczbę negocjacji połączeń. Zanim nie pobierzesz całych danych, to i tak nie wykorzystasz części już pobranej. 13:37 :>

To jak będę rządził to co będę negocjował ?

0

Tak, jak dotychczas: bez negocjacji (z innymi). ;)
Jeśli wysyłałbyś ogromne pliki, to dzielenie może miałoby jakiś sens, ale nie tak małe.
Poza tym… rekurencja? Może pętla lepsza.
Pokaż kod.

0

Nie wiem czy coś tu zobaczysz

class ManagerSesji {
    constructor(nazwa_pliku, tekst, obiekt) { //obiekt zbedny
        this.nazwa_pliku = nazwa_pliku;
        this.tekst = tekst;
        this.dlugosc = this.tekst.length;
        this.pozycja = 0;
        this.ilosc = Math.floor(this.tekst.length / 1500);
        this.reszta = (this.tekst.length - (this.ilosc * 1500));
        if (this.reszta > 0) { //zapis ostatniego elementu
            for (let i = 0; i < 1490 - (this.tekst.length - (this.ilosc * 1490)); i++) {
                this.tekst += " ";
            };
            this.ilosc++;
        }
        this.sesja = {
            nazwa: nazwa_pliku,
            moje_dane_majos: ""
        };
        this.headers = {
            'Content-Type': 'application/json', // Change to JSON content type
            'Custom-Header': 'some-value'
        };
    }

    wyslij_zapytanie_otwarcia_pliku() {
        window.top.tmp_obiekt = this;
        let jj = "";
        for (let i = 0; i < 900; i++) {
            jj += "f"
        }
        window.top.init_zapis_plik = {
            przygotuj_plik_Majosa2: this.nazwa_pliku + "3",
            dlugosc_Majosa2: this.dlugosc,
            dane: jj
        };
        fetch("http://localhost:8080/zs", {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Custom-Header': 'some-value'
            },
            body: JSON.stringify(window.top.init_zapis_plik)
        }).then(response => response.text()).then(data => {
            //alert("Etap 1 zakończony!");
            setTimeout(function () {
                window.top.tmp_obiekt.inicjacja();
            }, 800);
        }).catch(error => console.error("Error:", error));
    }

    inicjacja() {
        let obiekcik = window.top.tmp_obiekt;
        let ostatni = (obiekcik.pozycja + 1) * 1500;
        if ((obiekcik.pozycja == obiekcik.ilosc - 1) && obiekcik.reszta > 0) {
            ostatni = obiekcik.tekst.length;
        }
        let tmp = obiekcik.tekst.substring((obiekcik.pozycja * 1500), ostatni);
        window.top.tmp_obiekt.sesja.moje_dane_majos = sConvert(tmp);
        window.top.tmp_obiekt.wyslij_dane_do_pliku();
    }

    wyslij_dane_do_pliku() {
        fetch("http://localhost:8080/zs", {
            method: 'POST',
            headers: window.top.tmp_obiekt.headers,
            body: JSON.stringify(window.top.tmp_obiekt.sesja)
        }).then(response => response.text()).then(data => {
            if (window.top.tmp_obiekt.pozycja == window.top.tmp_obiekt.ilosc - 1) {
                window.top.zse.remove();
                alert("Etap 3 zakończony!");
                // window.top.tmp_obiekt.wyslij_zapytanie_zamkniecia_pliku();  
            } else {
                window.top.zse.children[0].style.width = ((100 / window.top.tmp_obiekt.ilosc) * (window.top.tmp_obiekt.pozycja + 2)) + "%";
                window.top.tmp_obiekt.pozycja++;
                let obiekcik = window.top.tmp_obiekt;
                window.top.start = 0;
                let ostatni = (obiekcik.pozycja + 1) * 1500;
                if ((obiekcik.pozycja == obiekcik.ilosc - 1) && obiekcik.reszta > 0) {
                    ostatni = obiekcik.tekst.length;
                }
                let tmp = obiekcik.tekst.substring((obiekcik.pozycja * 1500), ostatni);
                window.top.tmp_obiekt.sesja.moje_dane_majos = sConvert(tmp);
                // rekurencja
                window.top.tmp_obiekt.wyslij_dane_do_pliku();
            }
        }).catch(error => console.error("Error:", error));
    }

    wyslij_zapytanie_zamkniecia_pliku() {
        let jj = "";
        for (let i = 0; i < 900; i++) {
            jj += "f"
        }
        window.top.init_zapis_plik = {
            zamknij_plik_Majosa2: "sssss",
            dane: jj
        };
        fetch("http://localhost:8080/zs", {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Custom-Header': 'some-value'
            },
            body: JSON.stringify(window.top.init_zapis_plik)
        }).then(response => response.text()).then(data => {
            //setTimeout(function(){window.top.tmp_obiekt.wyslij_dane_do_pliku();},500);
        }).catch(error => console.error("Error:", error));
    }
}

//obiekcik = new ManagerSesji("pliczek.txt",txt,null); - tak się uruchamia
//obiekcik.wyslij_zapytanie_otwarcia_pliku();

// progress bar
function show_pb() {
    window.top.zse = document.createElement("DIV");
    document.body.appendChild(zse);
    zse.setAttribute("style", "position:absolute;display:flex;top:33%;left:20%;width:60%;height:10%;background-color:black;z-index:9700;");
    zse.innerHTML = "<label style='display:flex;top:0%;left:0%;width:10%;height:100%;background-color:white;z-index:9701;'></label>";
}


1.jpg

1

Jeśli ‘server’ zna długość pliku, to nie potrzebuje żądania zamknięcia pliku. Mógłby zamykać plik samoczynnie. Co się stanie, jeśli plik przestanie być wysyłany z jakiegoś powodu (np. odświeżenie strony lub błąd po stronie przeglądarki)? ‘Server’ mógłby sam tym zarządzać i po upływie czasu usuwać nie dosłany plik.
Rekurencję mógłbyś usunąć przy zastosowaniu async/await.
Natomiast co daje wysyłanie fragmentami, skoro i tak masz wszystko w pamięci przeglądarki:

this.tekst = tekst;

Jakkolwiek rozmiar fragmentu powinien być w zmiennej, by nie powtarzać wszędzie liczby.

setTimeout(function () {
    window.top.tmp_obiekt.inicjacja();
}, 800);

Po co jest ten ‘timeout’?
Nie usuwasz obiektu z window.top.tmp_obiekt.

0
overcq napisał(a):

Jeśli ‘server’ zna długość pliku, to nie potrzebuje żądania zamknięcia pliku. Mógłby zamykać plik samoczynnie. Co się stanie, jeśli plik przestanie być wysyłany z jakiegoś powodu (np. odświeżenie strony lub błąd po stronie przeglądarki)? ‘Server’ mógłby sam tym zarządzać i po upływie czasu usuwać nie dosłany plik.
Rekurencję mógłbyś usunąć przy zastosowaniu async/await.
Natomiast co daje wysyłanie fragmentami, skoro i tak masz wszystko w pamięci przeglądarki:

this.tekst = tekst;

Jakkolwiek rozmiar fragmentu powinien być w zmiennej, by nie powtarzać wszędzie liczby.

setTimeout(function () {
    window.top.tmp_obiekt.inicjacja();
}, 800);

Po co jest ten ‘timeout’?
Nie usuwasz obiektu z window.top.tmp_obiekt.

To jest pierwsza wersja robocza, połowa jest zbędna

W C to wygląda tak




zrodlo = strstr(buffer,"moje_dane_majos");


if(zrodlo!=NULL){
                 plik_do_zapisu = fopen(nazwa_pliku_do_zapisu,"ab");
                 zrodlo+=18;
                 for(long z=0;z<4500;z++){
                                           dodekodowania[z]=*zrodlo;
                                            if(*zrodlo==34){break;}else{zrodlo++;}}
                 send(clientSocket, resso, strlen(resso), 0);
                 dodekodowania[4500]='\0';

                 dekodowanie(&dodekodowania[0],&dodekodowania_wyjscie[0]);

                 dodekodowania_wyjscie[1500]='\0';

                 //printf("\n%s\n-- -----------------\n--",dodekodowania_wyjscie); - wyswietlanie pakietu

                 char *tmo = &dodekodowania_wyjscie[0];

                 printf("\npoczatek %d -- z --  %d",(int)dlugosc_pliku_do_zapisu_pozycja,dlugosc_pliku_do_zapisu);
                 for(int i=0;i<1500;i++){

                 // jesli wczytane tyle ile przekazane w rozmiarze to koniec
                 if((dlugosc_pliku_do_zapisu_pozycja > dlugosc_pliku_do_zapisu) || (dodekodowania_wyjscie[i]=='\0')){break;}
                 dlugosc_pliku_do_zapisu_pozycja+=(int)1;
                 fprintf(plik_do_zapisu,"%c",*tmo);tmo++;
                 }
                 printf("\nzapisane %d -- z --  %d",(int)dlugosc_pliku_do_zapisu_pozycja,dlugosc_pliku_do_zapisu);
                 fclose(plik_do_zapisu);

                 fgh++; // ile pakietow zostalo  dotad zapisanych
}
0

Odnośnie tego kodu z ‘servera’. Jakbyś zrobił pętlę na recv z danym buforem, to uzyskałbyś ten sam efekt, brak nadmiernego wykorzystania pamięci po stronie ‘servera’, ale bez ponownej, niepotrzebnej negocjacji połączenia ‘tcp’. Chyba że to jest celowe mieszanie z połączeniami, by zmusić nasłuchującego pomiędzy przeglądarką a ‘serverem’ do łączenia danych z odrębnych połączeń fetch, co jakkolwiek nie jest trudne.

0

Zrobiłem tak jak umiałem

to nadmierne wykorzystanie pamięci to gdzie?

Pliki docelowe na ramdysku, w pamięci programu 5000 bajtów 2 tablice, jeden buffer chya 20000 i tyle.

Dałem to zamknięcie pliku bo wcześniej nie zapisywałem pliku co pakiet tylko na końcu planowałem.

0

No właśnie piszę, że osiągnąłeś brak nadmiernego wykorzystania pamięci, ale ten sam efekt byś osiągnął łącznie z brakiem negocjacji połączeń.

0
overcq napisał(a):

No właśnie piszę, że osiągnąłeś brak nadmiernego wykorzystania pamięci, ale ten sam efekt byś osiągnął łącznie z brakiem negocjacji połączeń.

I progress bar by był na oknie?

0

Ja zawsze daje na swoje bufory 8192.
Samo pytanie jest dla mnie zbyt mało precyzyjne wiec pewnie nie pomogłem. ;-)

2

Zamiast pytać, popraw kod tak, by monitorował wydajność.
Zwiększając bufor wydajność zapewne będzie się zwiększać do pewnego momentu. Wyznaczając ten moment ustalisz praktycznie wielkość bufora.
Pamiętaj, że wynik pomiaru będzie specyficzny dla danego systemy / sieci.
Może warto sprawdzić jaka jest wartość MTU (Maximum Transmission Unit) dla interfejsu sieciowego, którego używasz.

0
ksh napisał(a):

Ja zawsze daje na swoje bufory 8192.
Samo pytanie jest dla mnie zbyt mało precyzyjne wiec pewnie nie pomogłem. ;-)

Jak daję większy niż 4000 to się sypie ale miałem sprawę, że zapisywało max 8 000 na dysku, więc coś w tym jest co piszesz. Nie jest łatwo mi ustawić, bo konwertuję całą wiadomość na inny kod (3 bajtowy) żeby nie wrzucać tych \" itp

0

Tak testuje przekaz czy idzie poprawnie sprawdzam (plik testowy wynikowy)
Powinno dojść coś takiego

let z="";
for(let i=0;i<6;i++){
                     for(let i2=0;i2<1499;i2++){
                                               z+=String.fromCharCode(i+48);};z+="A";z+="\n";}

1.jpg

0
overcq napisał(a):

Po co dzielić? (Żeby rządzić? ;) ) Najlepiej od razu całe dane. I tak dzielenie nic tutaj nie daje, a opóźnia i zwiększa liczbę negocjacji połączeń. Zanim nie pobierzesz całych danych, to i tak nie wykorzystasz części już pobranej. 13:37 :>

Bez sensu. Mając graf cykliczny nieskierowany nie można z góry zakładać że istnieje tylko jedna droga do celu. Moim zdaniem najlepiej dobrać rozmiar bufora robiąc pewną heurystyką - np. wysyłamy pakiet ping i wyciągamy z niego liczbę hopów. Dzięki temu możemy w przybliżeniu określić liczbę stopni swobody jaką nasza droga do celu może obrać. Następnie używając jej dzielimy to co chcemy wysłać i liczymy na pełne wykorzystanie zrównoleglonych połączeń równoczesnych.

0
loza_prowizoryczna napisał(a):
overcq napisał(a):

Po co dzielić? (Żeby rządzić? ;) ) Najlepiej od razu całe dane. I tak dzielenie nic tutaj nie daje, a opóźnia i zwiększa liczbę negocjacji połączeń. Zanim nie pobierzesz całych danych, to i tak nie wykorzystasz części już pobranej. 13:37 :>

Bez sensu. Mając graf cykliczny nieskierowany nie można z góry zakładać że istnieje tylko jedna droga do celu. Moim zdaniem najlepiej dobrać rozmiar bufora robiąc pewną heurystyką - np. wysyłamy pakiet ping i wyciągamy z niego liczbę hopów. Dzięki temu możemy w przybliżeniu określić liczbę stopni swobody jaką nasza droga do celu może obrać. Następnie używając jej dzielimy to co chcemy wysłać i liczymy na pełne wykorzystanie zrównoleglonych połączeń równoczesnych.

O tym nie pomyślałem, wysłać kilka fetch() na raz?

Nie wiem czy powinienem ...

Tylko w pamięci trzeba by to związać by rządzić wszystkimi

0
johnny_Be_good napisał(a):

Tylko w pamięci trzeba by to związać by rządzić wszystkimi

Używasz rekurencji więc czemu nie wykorzystać optymalizacji ogonowej? Ostatni gasi światło.

1

Czegoś nie rozumiem...

Po pierwsze - dlaczego to pytanie jest w dziale C/C++ ?
Po drugie - po co zamieniasz zawartość pliku na tekst zamiast wysłać dane binarne ?
Po trzecie - jak duże pliki przesyłasz, że w ogóle chcesz się w takie rzeczy bawić zamiast wysłać całość jednym PUT-em ?

Nie rozumiem też dyskusji o liczbie hop-ów, rozmiarze MTU itp - od tego mamy stos TCP/IP, żeby się takimi rzeczami za nas zajmował. Może w jakichś wyjątkowych sytuacjach warto się bawić w ręczny finetuning, ale litości - wysłanie pliku (nawet dużego) na serwer w normalnej sieci takim przypadkiem nie jest...

0
Bartłomiej Golenko napisał(a):

Czegoś nie rozumiem...

Po pierwsze - dlaczego to pytanie jest w dziale C/C++ ?
Po drugie - po co zamieniasz zawartość pliku na tekst zamiast wysłać dane binarne ?
Po trzecie - jak duże pliki przesyłasz, że w ogóle chcesz się w takie rzeczy bawić zamiast wysłać całość jednym PUT-em ?

Nie rozumiem też dyskusji o liczbie hop-ów, rozmiarze MTU itp - od tego mamy stos TCP/IP, żeby się takimi rzeczami za nas zajmował. Może w jakichś wyjątkowych sytuacjach warto się bawić w ręczny finetuning, ale litości - wysłanie pliku (nawet dużego) na serwer w normalnej sieci takim przypadkiem nie jest...

I jak się wtedy progress bar implementuje jak idzie jednym putem?

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