2016-06-20 12 views
0

Ich habe ein Problem mit Socket lesen, wo es versucht, mehr als 20 MB Daten aus Socket zu lesen, aber die Daten sollen aus Socket Byte Array von 4 gelesen werden. Ich bin ziemlich neu zur Socket Programmierung Welt ist also nicht wirklich etwas mit meiner Fassung las Methode genau falsch laufenJava Socket lesen mehr Daten als erwartet

Below für Socketverbindung meine open Methode

public void open(String catalogName, String sshHost, String port) { 
    String responseCode; 
    try {    
     socket = new Socket(sshHost, port); // java.net.Socket 
     socket.setSoTimeout(3 * 60 * 1000); // defaulting socket timeout to 3 minutes for now 

     input = socket.getInputStream(); 
     output = socket.getOutputStream();    

     String command = String.format("new|Provider=SQLOLEDB;;;Initial Catalog=%s;", catalogName); 
     logger.log(Level.DEBUG, "Executing Command: " + command); 
     output.write(getLittleEndianLength(command.length())); 
     output.write(command.getBytes()); 
     output.flush(); 
     responseCode = getResponse(); 
     if (!responseCode.equals(ERROR_RESPONSE_CODE)) { 
      throw new BaseApplicationException("Invalid response code when connecting to database:" + responseCode); 
     } 

    } catch (UnknownHostException e) { 
     throw new BaseApplicationException(e); 
    } catch (IOException e) { 
     try { 
      socket.close(); 
     } catch (Exception ee) {} 
     throw new BaseApplicationException(e.getMessage()); 
    }   
} 

Sobald die Socket-Verbindung geöffnet wird, ist versucht, die Daten zu lesen in Puffer, die ein Byte-Array der Größe 4 wie unten verwenden, und die Daten, die vom Socket gelesen werden, können nicht mehr als sein MAX_RX_LENGTH, die 20 MB

public String read() { 
    // read in the integer that defines the length of the result 
    byte[] b = new byte[4]; 
    int retval = 0; 

    try { 
     retval = read(b); 
     if (retval == -1) return null; 

     // convert the integer from Big Endian (used by C#) to little endian (java default) 
     ByteBuffer buffer = ByteBuffer.wrap(b); 
     buffer.order(ByteOrder.LITTLE_ENDIAN); 

     int numberBytes = buffer.getInt(); 
     if (numberBytes > MAX_RX_LENGTH) // MAX_RX_LENGTH = 20971520 which is 20 MB 
      throw new BaseApplicationException("Bytes to read was larger than max allowed. numberBytes=" 
        + numberBytes); 
     logger.log(Level.DEBUG, "reading " + numberBytes + " bytes"); 

     if (numberBytes > 0) { 

      byte[] bytes = new byte[numberBytes]; 
      int total = 0; 
      int bytesRead = 0; 
      // may not be able to read the full message in one try so need to loop 
      while (total < numberBytes && (bytesRead = read(bytes, total, numberBytes - total)) >= 0) { 
       logger.log(Level.DEBUG, "bytes read:" + bytesRead); 
       total += bytesRead; 
      } 

      return new String(bytes); 
     } 
    } catch (IOException e) { 
     try { 
      socket.close(); 
     } catch (Exception ee) {} 
     throw new BaseApplicationException(e.getMessage()); 
    } 
    return null; 

} 

public int read(byte[] b) throws IOException { 
    return input.read(b); 
} 

public int read(byte[] b, int off, int len) throws IOException { 
    return input.read(b, off, len); 
} 

In unserer Produktionsumgebung halten wir Ausnahmemeldungen wie Bytes to read was larger than max allowed. numberBytes=543584032 sehen, obwohl Sockel sollten Leseverfahren nur Byte-Array der Größe 4. Wir sehen nicht dieses Problem in pre-prod Umgebungen lesen. Kann mir jemand helfen, wie stelle ich sicher, dass die vom Socket gelesenen Daten weniger als 20 MB sind?

+0

Warum sollten Sie eine Verbindung zwischen dem Ergebnis von 'buffer.getInt()' und der Anzahl der gelesenen Bytes erwarten ?! –

Antwort

0

Sie haben die Zeichenfolge "of" als eine Zahl interpretiert und natürlich Unsinn bekommen. Der Fehler wird im Code nicht angezeigt, wodurch die Synchronisierung zwischen dem Absender und dem Empfänger verloren geht. Wenn der Absender einen Teil einer Zeichenfolge sendet, erwartet der Empfänger die Größe eines Blocks und wird daher unbrauchbar.

Verwandte Themen