Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    Trasferimento file tramite protocollo tcp

    Ciao,
    stavo facendo questo programma in php per trasferire un file da un pc a un altro, uso socket con AF_INET, SOCK_STREAM, SOL_TCP.
    Dunque il file non lo carico tutto sul buffer, perchè con i file di grandi dimensioni cn qualche GB occupa tutta la RAM, quindi faccio una lettura(rb) sequenziale e invio 4096 byte per volta con socket_write.
    Dall'altra parte il server che riceve, ha la dimensione del file totale, dunque ottengo per difetto quante volte 4096 viene inviato in modo da potermi creare il ciclo per la ricezione.
    Inoltre, dato che arrotondo per difetto, calcolo la differenza tra la dimensione totale del file e quella raggiunta alla fine del ciclo di ricezione, ossia:
    codice:
    $volte = floor($size /4096);
    $misura_raggiunta = $volte * 4096;
    ...e fuori dal ciclo della ricezione, faccio un ultimo socket_read e aggiungo la differenza mancante(che è sempre minore di 4096 byte) al file(wb) e chiudo.
    Ora...il programma in locale mi funziona, ho provato sia file piccoli, sia di grandi dimensioni e arrivano tutti fino all'ultimo byte.
    Provando in rete, con un file di 17 MB mi sono avvicinato quasi alla fine del file, tentando più volte, ho ottenuto misure simili ma cmq diverse tra loro, mentre con un file di testo, oltrepasso appena la metà del file.
    La lettura penso che funzioni bene, dato che il file di testo arriva correttamente, ma poi è come se venisse troncato.
    A cosa può essere dovuto?

    Un saluto

    Alberto
    Sistemi di allarme, telecamere, autoradio, video proiettori e altri prodotti tecnologici: fedom.it

  2. #2
    Utente di HTML.it
    Registrato dal
    Feb 2005
    Messaggi
    209
    Credo sia il fatto che $volte vada bene in locale, dove la possibilità di errore è tendente a 0.
    Mentre on-line le volte sono di più, infatti se avviene un errore, il protocollo TCP, a differenza di quello UDP, chiede nuovamente l'invio del pacchetto.

    Non ne sono certo, ma suppongo che questo sia il motivo.

  3. #3
    E' una bella risposta secondo me.
    Penso purtroppo che il rinvio dei pacchetti in caso di errore non avvenga in automatico, e ciò causa un problema nella ricezione....e dato che cambiano le $volte che bisogna leggere...che consigli?
    Però allo stesso tempo, se ottiene un errore nel trasferimento, socket_write dovrebbe dirmelo.
    L'unico errore che mi ha dato socket_write è stato proprio quando il file ricevente ha bloccato la lettura secondo le $volte e ha chiuso tutto pensando che i byte fossero finiti, mentre magari socket_write doveva inviare altra roba(cm pensi tu). (Mi riferisco in particolare al file da 17MB)
    Infatti mi diceva Connessione chiusa dall'host remoto o una cosa del genere.
    Ti parlo all'incirca della fine del file ma di un numero di byte persi più alto di 4096, e ciò mi fa pensare che l'errore non avvenga nell'ultima lettura, cioè quella che riguarda la differenza mancante.


    Un saluto

    Alberto

    EDIT:
    Nella documentazione PHP ho trovato:
    Il Transmission Control Protocol è un procotollo affidabile, basato sulla connessione, orientato al flusso, full duplex. Il TCP garantisce che tutti i pacchetti siano ricevuti nel medesimo ordine in cui siano stati inviati. Se un pacchetto viene perso durante la trasmissione, il TCP provvederà automaticamente alla ritrasmissione fino a quando l'host remoto non conferma la ricezione dello stesso. Per ragioni di affidabilità e di prestazioni, è il TCP stesso a decidere l'appropriata dimensione dei pacchetti del sottostante livello di datagrammi. Pertanto le applicazioni TCP devono permettere la parziale ritrasmissione di un record.

    Dunque in automatico sembra accollarsi il tutto...però dalla parte del server che riceve, devo gestirlo cmq io questo fatto?
    Sistemi di allarme, telecamere, autoradio, video proiettori e altri prodotti tecnologici: fedom.it

  4. #4
    up
    Sistemi di allarme, telecamere, autoradio, video proiettori e altri prodotti tecnologici: fedom.it

  5. #5
    Utente di HTML.it
    Registrato dal
    Feb 2005
    Messaggi
    209
    Data la natura del protocollo l'idea di decidere che quelle volte sono sufficienti è aleatoria, nemmeno se creassi un algoritmo che aggiungesse volte in base a una statistica basata sulle percentuale di errori.
    In questo tipo di trasmissioni si richiede un feedback, perciò se hai creato un server TCP con PHP senza usare i thread, hai sicuramente utilizzato un ciclo infinito.

    Nella funzione che richiami per mandare il file, lì dentro dovrebbe esserci un secondo ciclo infinito che viene interrotto quando si arriva al closer del file inviato, finito il ciclo, server e client si disimpegnano.

  6. #6
    Originariamente inviato da SPiNALeX
    Data la natura del protocollo l'idea di decidere che quelle volte sono sufficienti è aleatoria, nemmeno se creassi un algoritmo che aggiungesse volte in base a una statistica basata sulle percentuale di errori.
    In questo tipo di trasmissioni si richiede un feedback, perciò se hai creato un server TCP con PHP senza usare i thread, hai sicuramente utilizzato un ciclo infinito.

    Nella funzione che richiami per mandare il file, lì dentro dovrebbe esserci un secondo ciclo infinito che viene interrotto quando si arriva al closer del file inviato, finito il ciclo, server e client si disimpegnano.
    Ciao, dunque la parte che avevo fatto per inviare il file è questa:
    Codice PHP:
    $handle fopen($filename"rb");
    $contents "";
    $a 0;    
    $b 4096;
    $times sprintf("%u"filesize($filename))/4096;
    fseek($handle0SEEK_SET); 
    while (!
    feof($handle))  
    {            
    //echo "La posizione del puntatore è: ".ftell($handle)."\n";                            
    $contents = @fread($handle,4096);
    if(
    sprintf("%u",ftell($handle)) % 4096 == 0
    {
    fseek($handle$bSEEK_SET);
    $b $b 4096;                                
    }
    socket_write($socket$contents,strlen($contents));                            
    }
    echo 
    "*File inviato.*\n";
    unset(
    $contents);
    fclose($handle);
    socket_close($socket); 
    Il codice all'interno del ciclo viene effettuato tante volte fino a quando non si raggiunge la fine del file.
    Mentre la parte che riceve è questa:
    Codice PHP:
    $times floor($size /4096);
    $newsize $times 4096;        
    $differenza $size $newsize;
    for(
    $a=1;$a<=$times$a++)
    {    
    $data socket_read($conn4096) or die("Could not read input\n");                    
    fwrite($handle$data);        
    }  
    $data1 socket_read($conn$differenza) or die("Could not read input\n"); 
    fwrite($handle$data1);                      
    fclose($handle);
    echo 
    "File salvato con succcesso";
    socket_close($conn);
    socket_close($socket); 
    Appena dovrebbe arrivare il file io chiudo tutto, intendevi altro?
    Ciao
    Sistemi di allarme, telecamere, autoradio, video proiettori e altri prodotti tecnologici: fedom.it

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2005
    Messaggi
    209
    Ci sono altri modi per inviare file, prova a vedere le librerie cURL.
    Perchè il server riceva tutto il file non deve chiudersi dopo n volte, ma alla fine della trasmissione.
    Tempo fa ho scritto una classe per creare un daemon socket programmabile, lo puoi raggiungere tramite telnet e lo lanci da browser con socket.php.

    L'indirizzo è Daemon socket 0.2

    L'idea è: programmi il daemon con una funzione per ricevere il file, lanci il daemon da browser, lo raggiungi con un altro script che apra il daemon e chiami la sua funzione per la ricezione di un file.

    Non chiedermi di provare a farlo perchè non ho tempo, ma almeno guardando i sorgenti di un server socket persistente ti si dipana qualche dubbio sul funzionamento.


    Ciao :master:

  8. #8
    Ciao,
    alla fine sono riuscito tramite socket_shutdown e nn si perde niente per strada,
    grazie per l'aiuto

    Buona giornata
    Sistemi di allarme, telecamere, autoradio, video proiettori e altri prodotti tecnologici: fedom.it

  9. #9
    Utente di HTML.it L'avatar di dottwatson
    Registrato dal
    Feb 2007
    Messaggi
    3,012
    Originariamente inviato da Albertorrr
    Ciao,
    alla fine sono riuscito tramite socket_shutdown e nn si perde niente per strada,
    grazie per l'aiuto

    Buona giornata
    in pratica utilizzi uno stream tramite socket...

    ma il timeout di php.ini? inoltre sei anche in grado di stabilire la velocità di trasferimento, rendendo cosi' il packet size equo nelle dimensioni?
    Non sempre essere l'ultimo è un male... almeno non devi guardarti le spalle

    il mio profilo su PHPClasses e il mio blog laboweb

  10. #10
    Allora per il limite imposto set_time_limit(0); per quanto riguarda la velocità di trasferimento, non dipende da me, cioè io invio la roba, il protocollo tcp tenta di inviare il pacchetto finchè non viene accettato, il server riceve fino a quando il client non si disconnette tramite shutdown su scrittura.
    Io cmq invio sempre 4096 e ricevo a blocchi da 4096.
    Per calcolare la velocità di trasferimento penso che bisogna mettere nel ciclo di ricezione qualcosa tipo V = S/tempo, quindi velocità di trasferimento = Bytes/tempo, basandomi sulla lunghezza della stringa che talvolta ottengo cn socket_read.
    Ma vorrei risolvere una cosa prima.
    Quando in linea di comando io faccio più echo sequenzialmente, l'ouput si allunga sempre di più, esiste un modo per modificare la stessa zona di output?
    Tipo
    echo "ciao";
    echo "ciao";
    Output non: ciaociao
    ma: ciao
    Cioè in modo tale da aggiornare la stessa posizione, altrimenti se devo fare la stima per i byte ricevuti mi si creano un bordello di linee, mentre io vorrei modificare una porzione e basta.

    Qualcuno sa cm fare?

    Ciao
    Sistemi di allarme, telecamere, autoradio, video proiettori e altri prodotti tecnologici: fedom.it

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.