2013-11-27 82 views
0

下面的代碼是較大嘗試的一部分;它試圖在服務器和客戶端之間傳輸文件的詳細信息,並且失敗。服務器向套接字寫入3個元素,客戶端應接收相同的3個元素。讀取第一個元素後,客戶端塊我究竟做錯了什麼?!?通過Java套接字發送文件詳細信息失敗

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層回事。當你從BufferedReader中調用readLine()時,它可能會繼續並從底層流中竊取更多的字節,因爲這就是它應該做的。然後,當您返回DataInputStream並嘗試讀取一個對象時,前導碼就會消失(BufferedReader竊取它),並且會阻塞等待它,儘管流中有字節。

+0

謝謝喬恩!但是有沒有解釋呢?爲什麼我的客戶在第一次讀取後會被阻塞?我應該避免完全像這樣的級聯流嗎?畢竟,它們被設計爲級聯... – user3043540

+0

@ user3043540請參閱我的答案中的解釋,我已經編輯它 –

+0

謝謝,這是有道理的。我錯誤地認爲BuferedReader只讀取一行並停止。好的,如果發生這種情況,我不應該混合流;但是如果我不創建一些高級流來幫助我,那麼我怎樣才能通過單個套接字發送各種類型的數據(字符串,文件內容,原始值等)? – user3043540