2012-04-06 65 views
2

運行多線程服務器程序下面是服務器端的代碼不能夠在Java中

package echoserver; 

import java.net.*; 
import java.io.*; 

public class EchoServer { 

    public static void main(String[] args) { 
     try { 

      //establish server socket 
      ServerSocket s = new ServerSocket(1981); 

      //Thread client connectionsincoming 
      while (true) { 
       //wait for incoming connection 
       Socket incoming = s.accept(); 
       Runnable r = new ThreadedEchoHandler(incoming); 
       Thread t = new Thread(r); 
       t.start(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 


package echoserver; 

import java.net.*; 
import java.util.*; 
import java.io.*; 

class ThreadedEchoHandler implements Runnable { 

    public ThreadedEchoHandler(Socket i) { 
     //initializing socket 
     incoming = i; 
    } 

    public void run() { 
     try { 
      try { 
       //recieve input stream from socket 
       InputStream inStream = incoming.getInputStream(); 

       //recieve output stream from socket 
       OutputStream outStream = incoming.getOutputStream(); 

       //Create a scanner from input stream 
       Scanner scan = new Scanner(inStream); 

       //Create printer writer from output stream and enabled auto flushing 
       PrintWriter out = new PrintWriter(outStream, true); 

       //prompt users on how to exit program soon as a long in into the server 
       out.println("Enter BYE to exit"); 

       boolean done = false; 

       //while done is not true and scanner has next line loop 
       while (!done && scan.hasNextLine()) { 

        //reading text that came in from the socket 
        String line = scan.nextLine(); 

        //On the server print the ip address of where the text is coming from and the text they typed 
        System.out.println("Recieved from " + incoming.getInetAddress().getHostAddress() + ": " + line); 

        //Echo back the text the client typed to the client 
        out.println("Echo: " + line); 

        //if they type BYE in caps terminate there connection and I also trimmed whitespaces 
        if (line.trim().equals("BYE")) { 
         done = true; 
        } 
       } 
      } //finally close the socket connection 
      finally { 
       incoming.close(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    private Socket incoming; 
} 

,這裏是

package client; 

import java.net.*; 
import java.io.*; 

public class Client { 

    public static void main(String[] args) throws IOException { 
     PrintWriter out = null; 
     try { 
      Socket s = new Socket(InetAddress.getLocalHost(), 1981); 
      System.out.println("Connected to server on port 1981"); 
      out = new PrintWriter(s.getOutputStream()); 

      out.println("Hello"); 
      s.close(); 

     } catch (Exception ex) { 
      System.err.println(ex.getMessage()); 
     } 
    } 
} 

Socktes越來越成功創建客戶端的代碼,但是當控制權轉至噸。 start()方法調用它不調用ThreadedEchoHandler類的run()方法。

這是怎麼發生的?任何想法?

回答

2

客戶端將"Hello"寫入PrintWriter。到現在爲止還挺好。

您可能期望PrintWriter直接將此文本發送到套接字,但它不會。來自PrintWriter(OutputStream)構造函數的文檔說,它創建了PrintWriter而沒有自動行沖洗。這意味着,只要您想要實際發送某些內容,就必須致電out.flush()

在您撥打out.flush()之前,文本僅存在於某個內部緩衝區中,服務器將無法看到它。

+0

非常感謝。 你的答案拯救了我的一天... – 2012-04-06 11:40:32

0

我的猜測是,因爲沒有客戶端連接到服務器,所以acept語句永遠被阻塞。你可以在打印中包裝accept()來證明或反駁。

+0

如果我們嘗試調試它,那麼控制轉到t.start(),然後再轉到s.accept()。它不會調用運行方法 – 2012-04-06 11:15:14

+1

@Nilesh Barai你怎麼知道這個?如果用調試器遍歷代碼,那麼不行,調試器不會切換到新創建的線程,您必須在該代碼中設置斷點。 – nos 2012-04-06 11:17:07

+0

找到它... 它正在調用run方法。 在while循環的run()方法中scan.hasNextLine()表示沒有任何可掃描的內容並退出。 所以我覺得有一些問題,客戶然後 – 2012-04-06 11:32:09