最近學習JAVA網絡編程,在服務器端和客戶端產生一個Socket 後,
兩邊各自用getIputStream()和getOutputStream()方法,構造各自的輸入輸出流。
其中服務器端的Socket ss
BufferedReader is=new BufferedReader(new InputStreamReader(ss.getInputStream()) );
PrintWriter os=new PrintWriter (new OutputStreamWriter(ss.getOutputStream()) );
os.writer("一個亂七八糟的字符串");
客戶端的Socket cs
BufferedReader is=new BufferedReader(new InputStreamReader(cs.getInputStream()) );
PrintWriter os=new PrintWriter (new OutputStreamWriter(cs.getOutputStream()) );
System.out.println(is.readLine());
按理說,應該是ss的 os對應著cs的 is. 為什麼在服務器端寫入了,在客戶端這邊沒法讀出來呢?
另外,如果服務器端用os.println("字符串");就好使了。
請問這是問什麼?
以下整理了開源中國社區的回答:
print() 方法等同於 write() 方法
println() 方法是在 print() 的基礎上多調用了一個 newLine() 方法(私有方法)
而 newLine() 方法會調用 flush()
所以關鍵在於 flush()
最好有個人能好好解釋解釋有關IO中的輸出流中的writer。以及如何從一個輸出流中提取用write()方法寫入到該流中的字符。
btw socket通信最好使用DataInputStream和DataOutputStream去封裝讀寫的操作,或者用 ObjectInputStream和ObjectOutputStream,而不要使用你寫的BufferedReader和 BufferedWriter。
問題主要集中在,為什麼客戶端調用了write()和flush()後,服務器端依然read不到數據。因為 socket.getOutputStream()取到的實現類是java.net.SocketOutputStream,這個類並沒有覆寫flush 方法,它的父類java.io.FileOutputStream也沒有覆寫,於是最終就調到了最頂層java.io.OutputStream的 flush()方法,這就惡心了,這個方法是空的。於是...
因此,還是使用Reader.readLine()和Writer.println()來處理socket吧,或者直接使用NIO。
(注意,SocketOutputStream類在JavaDoc中不存在,只在源碼中有,他是個受保護的類。)
print() 方法等同於 write() 方法
println() 方法是在 print() 的基礎上多調用了一個 newLine() 方法(私有方法)
而 newLine() 方法會調用 flush()
所以關鍵在於 flush()