2016-06-16 11 views
-1

クライアントからサーバまで約500kbのバイト配列を送信する必要があり、ヒープスペースエラー(約1または2GBのバイト配列を作成しようとしています)が発生することがあります。 -Xmx」コマンドは、[パッケージのサイズ] + [データのチャンク]クライアント/サーバ転送バイト配列のチャンク、ヒープスペースエラー

ここでのコードだ

バイト配列構造を助けるいけません。

クライアント:

public class Client_mk1 { 
public static void main(String[] args) throws IOException { 

     Socket socket = new Socket("localhost", 3030); 
     Client_mk1 clientMk1=new Client_mk1(); 

     FileInputStream fileInputStream=null; 

     File file = new File("SOMEFILE"); 

     byte[] data = new byte[(int) file.length()]; 

     System.out.println("file size"+(int) file.length()); 
     fileInputStream = new FileInputStream(file); 
     fileInputStream.read(data); 
     fileInputStream.close(); 
     clientMk1.ToChunks(socket,data); 


} 

void ToChunks (Socket socket, byte[] data) throws IOException { 

    BufferedOutputStream outputstream = new BufferedOutputStream(socket.getOutputStream()); 

    int chunksize = 50*1024; 
    int length = data.length; 

    for (int i = 0; i < length - chunksize + 1 ; i+= chunksize) { 

     byte[] datasize =IntToByteArray(chunksize); 
     ByteBuffer byteBuffer = ByteBuffer.allocate(chunksize + datasize.length); 

     System.out.println("TRY TO SEND "+IntFromByteArray(datasize)); 

     byteBuffer.put(datasize); 
     byteBuffer.put(Arrays.copyOfRange(data, i, i + chunksize)); 
     outputstream.write(byteBuffer.array()); 

     outputstream.flush(); 
    } 
    if (length % chunksize !=0){ 
     byte[] datasize = IntToByteArray(length % chunksize); 
     ByteBuffer bytebuffer = ByteBuffer.allocate((length % chunksize) + datasize.length); 
     System.out.println("TRY TO SEND "+IntFromByteArray(datasize)); 
     bytebuffer.put(datasize); 
     bytebuffer.put(Arrays.copyOfRange(data, length - length % chunksize, length)); 
     outputstream.write(bytebuffer.array()); 

     outputstream.flush(); 
    } 
} 

public static byte[] IntToByteArray(int value) { 
    return new byte[] { 
      (byte)(value >> 24), 
      (byte)(value >> 16), 
      (byte)(value >> 8), 
      (byte)value }; 
} 
public static int IntFromByteArray(byte[] bytes) { 
    return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF); 
} 

サーバー:

public class Server_mk1 implements Runnable { 
Socket socket; 

Server_mk1(Socket socket){ 
    this.socket=socket; 
} 

public static void main(String[] args) throws IOException { 
    ServerSocket serversocket = new ServerSocket(3030); 

    while (true){ 
     Socket socket = serversocket.accept(); 
     Thread dd=new Thread(new Server_mk1(socket)); 
     dd.start(); 
    } 



} 

public void run() { 


    BufferedInputStream bufferedInputStream = null; 
    try { 
     bufferedInputStream = new BufferedInputStream(this.socket.getInputStream()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 



    while (true){ 
     try { 
      byte[] size=new byte[4]; 

      System.out.println("Reading"); 
      bufferedInputStream.read(size); 

      System.out.println("SIZE "+Client_mk1.IntFromByteArray(size)); 

      //PROBLEM HERE create to big array for java heap space 
      byte[] recievedData=new byte[Client_mk1.IntFromByteArray(size)];//PROBLEM create to big array for java heap space 
      bufferedInputStream.read(recievedData); 


      System.out.println(new String(recievedData)); 
     }catch (Exception e){ 

      break; 
     } 

    } 
    System.out.println("RUNNING ON _"+Thread.currentThread().getName()); 
} 

は私が間違って何をしているのですか?

答えて

2

あなたは多くのことを間違っています。細部の細部にはsocket.getOutputStream()と書いてありますが、ちょっとばかげています。あなたのByteBufferコードは、ソケットにデータを書き込むよりも複雑である必要があり、何らかの理由でforループを使用していると思われます。ソケット通信の仕組みを実際に理解していないからでしょう。

お客様のクライアントコードは、次のように置き換えられます(soutSocketOutputStream)。あなたがavailable()を使用しているので、

sout.write(IntToByteArray(data.length)); 
sout.write(data); 
sout.close(); 

サーバーが壊れている、あなたはそれが何をするか理解していません。一言で言えば、available()を使用しないでください、あなたはそれを必要とすることは決してありませんし、あなたを助けることはありません。

byte[] buf = new byte[8192]; // A smallish buffer to read the bytes 
int bytesRead = 0; // Track the amount of bytes we actually read 
while((bytesRead = in.read(byte) != -1) { // -1 indicates end of stream 
    // buf now contains bytesRead amount of new bytes to be processed 
} 

を次のようにInputStreamからデータを読み込むための基本的なイディオムであるあなたがSocketsByteBufferで作業しているので、私は少し困惑している、まだあなたのコードの残りの部分は非常に素人に見えます。

関連する問題