# langsames streamen



## H-net (25. Apr 2009)

hi..

ich will eine datei über einen socket versenden, möchte aber gerne die geschwindigkeit mit der die datei übermittelt werden soll einstellen(z.b. 10kb/s). wie mache ich das?
Tread.sleep(1) ist viel zu ungenau
das ist der code der an den socket sendet:

```
RandomAccessFile outFile = new RandomAccessFile("xxxxxxxx","r");
Socket t = ssocket.accept();
OutputStream out2 = t.getOutputStream();

byte bb[] = new byte[1024];
int amount;
try {
     while ((amount = outFile.read(bb)) != -1) {
          out2.write(bb, 0, amount);
     }
     out2.close();
     outFile.close();
     t.close();
} catch (IOException e) {
}
```


----------



## SlaterB (25. Apr 2009)

sende 10kb und warte Thread.sleep(1000), 1000 ms  = 1 sec


----------



## H-net (25. Apr 2009)

ok das geht, aber gibts keine elegantere methode?


----------



## SlaterB (25. Apr 2009)

mir fällt logisch gesehen keine andere ein, von eleganter ganz zu schweigen,
man kann natürlich noch weiter stückeln, alle 100 ms 1000 bytes,
ob das in einem Netzwerk mit bestimmten Paketgrößen Sinn macht, sei dahin gestellt,

falls du fertige APIs suchst, die das erledigen: ich kann dazu keine nennen


----------



## tuxedo (28. Apr 2009)

Ich glaube im Mina-Framework (mina.apache.org) gibts einen Filter oder eine API-Funktion mit der man die Bandbreite einstellen kann. Also entweder MINA benutzen, oder schauen wie die's implementiert haben.

- Alex


----------



## Gelöschtes Mitglied 5909 (28. Apr 2009)

Das hier funktioniert eigentlich ganz gut:

wenn dir das erhöhen zu schnell geht kannst du sleep -=2 (statt sleep--) oder so machen

wenn das verlangsamen zu lahm ist mach sleep += 3 (oder mehr)

[highlight="java"]
import java.io.FilterOutputStream;
import java.io.IOException;
import java.iutputStream;

public class LimitedOutputStream extends FilterOutputStream {

    protected int  bps   = Integer.MAX_VALUE;

    protected long t0    = -1;

    protected long bytes = 0;

    protected int  rate  = Integer.MAX_VALUE;

    protected int  slept = 1;

    public LimitedOutputStream( OutputStream out, int bps ) {
        super(out);
        this.bps = bps;
    }

    public LimitedOutputStream( OutputStream out ) {
        this(out, Integer.MAX_VALUE);
    }

    @Override
    public void write( int b ) throws IOException {
        if ( bps == Integer.MAX_VALUE ) {
            super.write(b);
            return;
        }
        if ( t0 == -1 ) {
            t0 = System.currentTimeMillis();
            try {
                Thread.sleep(1000);
            } catch ( InterruptedException e ) {
            }
        }
        if ( rate >= bps ) {
            try {
                Thread.sleep(200 * slept);
                slept += 2;
            } catch ( InterruptedException e ) {
            }
        }
        else if ( slept > 0 ) {
            slept--;
        }
        super.write(b);
        bytes++;
        rate = calculateRate(t0, System.currentTimeMillis(), bytes);
    }

    public int getRate() {
        return rate;
    }

    public void setBps( int bps ) {
        this.bps = bps;
    }

    private static int calculateRate( long start, long end, long sent ) {
        try {
            return (int) (sent / ((end - start) / 1000));
        } catch ( ArithmeticException e ) {
            return 0;
        }
    }

}

[/highlight]

[highlight="java"]
import java.io.IOException;

public class Main {

    public static void main( String[] args ) throws IOException {
        LimitedOutputStream out = new LimitedOutputStream(System.out, 200);
        for ( int i = 0; i < 10000; i++ ) {
            out.write(32);
            System.out.println(out.getRate() + "b/s");
            if ( i == 100 ) {
                System.out.println("RATE Änderung");
                out.setBps(1024);
            }
        }
    }

}

[/highlight]


----------

