2012-02-13 2 views
3

Я выполняю работу сокетов в Java и пытаюсь кодировать передаваемые данные. Эта часть работает правильно, но по какой-то причине она не отправляет целую закодированную строку поверх сокета. Кажется, чтобы послать его в части 3.PrintWriter только отправляет часть строки Java

Клиент выполняет простую ReadLine() из класса MyBufferedReader (что ниже), а сервер посылает его следующим образом:

private void sendFile(File f, String dest){ //The file to be sent and the destination 
     System.out.println("Sending file started.."); 

     try { 
      this.out.println("CMD MKFILE " + dest + "/" + f.getName()); 
      //TODO send the file 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

Клиент получает это: CMD MKFILE C:\Users\Lolmewn\Documents\test/dir/n/linebrea и после того, как другой прочитал k!.txt

В MyBufferedReader и MyPrintWriter классы выглядеть следующим образом:

MyBufferedReader:

@Override 
    public String readLine() throws IOException { 
     String read = super.readLine(); 
     System.out.println("UNDEC: " + read); 
     try { 
      System.out.println("DEC: " + decode(read)); 
      return decode(read); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return read; 
    } 

    public static String decode(String b) throws Exception { 
     ByteArrayInputStream bais = new ByteArrayInputStream(b.getBytes("UTF-8")); 
     InputStream b64is = MimeUtility.decode(bais, "base64"); 
     byte[] tmp = new byte[b.length()]; 
     int n = b64is.read(tmp); 
     byte[] res = new byte[n]; 
     System.arraycopy(tmp, 0, res, 0, n); 
     return new String(res); 
    } 

и MyPrintWriter:

private String hash(String x) { 
     try { 
      return encode(x); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return x; 
    } 

    public static String encode(String b) throws Exception { 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     OutputStream b64os = MimeUtility.encode(baos, "base64"); 
     b64os.write(b.getBytes("UTF-8")); 
     b64os.close(); 
     return new String(baos.toByteArray()); 
    } 

То, что происходит, и как я могу это исправить?

Обратите внимание: я выполняю асинхронную работу над этими сокетами, то есть я не могу просто использовать какое-то время (read! = Null). Это может привести к тому, что другие данные не должны быть там.

ответ

1

Вначале это в сторону: если вы отправляете из нескольких потоков/клиентов, тогда вы должны открыть один сокет для каждого из них (например, accept()), тем самым сообщения от разных клиентов не могут чередовать друг друга.

Теперь я предполагая только один клиент за сокет (разумные):

Я не могу просто использовать время

Вы должны выполнить простой (читай! = NULL) протокол, с помощью которого вы можете отличить одно сообщение от следующего, например используйте 0-байт, если это никогда не может быть частью данных или префикс сообщения с длиной сообщения и отправить оба; таким образом ваш сервер может отличить одно сообщение от следующего.

+0

Я различаю их, добавляя в конкретном случае «CMD» спереди. Возможно, я мог бы создать более одного сокета, но каждый из них должен был бы снова войти в систему. Пароль SHA-512 зашифрован, и я уверен, что есть безопасный способ его сохранить, но мне не нравится идея о том, что где-то там где-то где-то болтается пароль. – Lolmewn

+0

Я не понимаю, почему будет другой вход в систему. Вам не нужно создавать еще один прослушивающий сокет на сервере, просто вызовите метод acceptS() ServerSocket, чтобы эффективно дублировать сокет. –

+0

Самое первое, что он делает, когда новый сокет создается, используя accept(), проверяет учетные данные для входа. Это, конечно, чтобы все было в безопасности. – Lolmewn

Смежные вопросы