2012-03-12 19 views
8

Sunucu-İstemci uygulamasını geliştiriyorum ve giriş akışıyla ilgili girdi verilerini beklerken bir sorunum var.Java InputStream verileri bekletir.

Giriş verilerini okumaya özel bir iş parçacığım var. Şu anda veri kullanılabilir olana kadar tutmak için döngü sırasında kullanır. (N.B. protokolü şu şekildedir: paketin boyutlarını gönderin, N, int sonra N bayt gönderin).

public void run(){ 
    //some initialization 
    InputStream inStream = sock.getInputStream(); 
    byte[] packetData; 
    //some more stuff 
    while(!interrupted){ 
     while(inStream.available()==0); 
     packetData = new byte[inStream.read()]; 
     while(inStream.available()<packetData.length); 
     inStream.read(packetData,0,packetData.length); 
     //send packet for procession in other thread 
    } 
} 

İş parçacığı IMO çalışırken kötü bir fikir çalışırken iş parçacığı engelleme ancak çalışır. Döngü tarafından sürekli olarak tüketilen kaynakları önlemek için Thread.sleep (X) kullanabilirim, ama mutlaka daha iyi bir yol olmalı.

Ayrıca, girdinin bir parçası olarak iş parçacığı tarafından gecikme ile gönderilebilmesini engellemek için InputStream.read belgesine güvenemiyorum. Denedim ama her zaman beklenmedik davranışlarla sonuçlandı.

Ben herhangi bir fikir takdir ediyorum :)

+2

InputStream.read zaten blokları veri mevcut değildir . yani "mevcut" yöntemini atın. – UmNyobe

cevap

12

Sen

DataInputStream in = new DataInputStream(sock.getInputStream()); 
//some more stuff 
while(!interrupted) { 
    // readInt allows lengths of up to 2 GB instead of limited to 127 bytes. 
    byte[] packetData = new byte[in.readInt()]; 
    in.readFully(packetData); 
    //send packet for procession in other thread 
} 

ben yeniden kullanılabilir tamponlarını destekler NIO engelleme kullanmayı tercih() DataInputStream.readFully kullanabilirsiniz.

SocketChannel sc = 
ByteBuffer bb = ByteBuffer.allocateDirect(1024 *1024); // off heap memory. 

while(!Thread.currentThread.isInterrupted()) { 
    readLength(bb, 4); 
    int length = bb.getInt(0); 
    if (length > bb.capacity()) 
     bb = ByteBuffer.allocateDirect(length); 
    readLength(bb, length); 
    bb.flip(); 
    // process buffer. 
} 



static void readLength(ByteBuffer bb, int length) throws EOFException { 
    bb.clear(); 
    bb.limit(length); 
    while(bb.remaining() > 0 && sc.read(bb) > 0); 
    if (bb.remaining() > 0) throw new EOFException(); 
} 
+3

Muhtemelen 2GiB'i hafızanıza okumak istemezsiniz –

4

UmNyobe dediği gibi, available() sen varsayılan davranışı engelliyor olarak bloke etmek istemiyorum durumunda kullanılmak üzere tasarlanmıştır.

Sadece mevcut ne varsa okumak ancak diğer iplik Eğer tampon içerisinde packetData.length bayt sahip kez işlenmek üzere sadece gönderme paket ... normal read kullanmak

+0

Teşekkürler ... Günümü kurtardım. – Velu

İlgili konular