2013-11-27 4 views
0

Код ниже является частью более крупной попытки; он пытается передать данные файла между сервером и клиентом и терпит неудачу. Сервер записывает 3 элемента в сокет, клиент должен получать одинаковые 3 элемента. Клиент блокирует чтение первого элемента. Что я делаю не так?!?Отправка сведений о файле через java socket

public class SocketIssues { 

    static void client() throws Exception { 

     new Thread() { 

      @Override 
      public void run() { 

       try { 
        Thread.sleep(1000); // enough time for server to open its socket 
        Socket s = new Socket("localhost", 50001); 

        final DataInputStream dis = new DataInputStream(s.getInputStream()); 
        final BufferedReader in = new BufferedReader(new InputStreamReader(dis)); 
        System.out.println("CLIENT STARTED"); 
        System.out.println("Operation: " + in.readLine()); 
        System.out.println("Length: " + dis.readLong()); 
        System.out.println("Name: " + dis.readUTF()); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

      } 

     }.start(); 

    } 

    static void server() throws Exception { 

     ServerSocket ss = new ServerSocket(50001); 
     Socket s = ss.accept(); 
     System.out.println("SERVER: client connected"); 
     DataOutputStream dos = new DataOutputStream(s.getOutputStream()); 
     BufferedWriter out = new BufferedWriter(new OutputStreamWriter(dos)); 
     long l = 2194; 
     String nume = "The file name"; 

     out.write("FILE1" + System.lineSeparator()); 
     out.flush(); 
     dos.writeLong(l); 
     dos.flush(); 
     dos.writeUTF(nume); 
     dos.flush(); 
     System.out.println("SERVER: done sending" + System.lineSeparator()); 
    } 

    public static void main(String[] args) throws Exception { 
     client(); 
     server(); 

    } 
} 

ответ

1

Попробуйте придерживаться только с DataOutputStream вместо смешивания их между данными и буферной методой писателем и использовать для чтения/запись UTF(), как вы уже делаете с последним объектом:

DataOutputStream dos = new DataOutputStream(s.getOutputStream()); 
    long l = 2194; 
    String nume = "The file name"; 

    dos.writeUTF("FILE1"); 
    dos.flush(); 
    dos.writeLong(l); 
    dos.flush(); 
    dos.writeUTF(nume); 
    dos.flush(); 
    System.out.println("SERVER: fisier trimis" + System.lineSeparator()); 

затем в клиенте:

   final DataInputStream dis = new DataInputStream(s.getInputStream()); 
       System.out.println("CLIENT STARTED"); 
       System.out.println("Operation: " + dis.readUTF()); 
       System.out.println("Length: " + dis.readLong()); 
       System.out.println("Name: " + dis.readUTF()); 

по существу, есть 2 слоя буферизация происходит. Возможно, когда вы вызываете readLine() из BufferedReader, он идет вперед и крадет больше байтов из базового потока, потому что, как хорошо, это то, что он должен делать. Затем, когда вы возвращаетесь к DataInputStream и пытаетесь прочитать объект, преамбула исчезла (BufferedReader украл его), и он будет блокировать его ожидание, хотя в потоке есть байты.

+0

Спасибо, Джон! Но есть ли объяснение этому? Почему мой клиент блокируется после первого чтения? Должен ли я вообще избегать каскадных потоков? В конце концов, они были разработаны для каскадирования ... – user3043540

+0

@ user3043540 См. Объяснение в моем ответе, я его отредактировал –

+0

Спасибо, это имеет смысл. Я ошибочно предположил, что BuferedReader только считывает строку и останавливается. Итак, если это так, я не должен смешивать потоки; но тогда как я могу отправлять различные типы данных (строка, содержимое файла, примитивные значения и т. д.) через один сокет, если я не создаю потоки высокого уровня, чтобы помочь мне в этом? – user3043540

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