2013-03-02 242 views
1

我製作了一個基於TCP/IP的基本項目,其中服務器監聽客戶端,然後提供傳入數據的大寫句子。簡單客戶端服務器程序

Server.java:

import java.io.*; 
import java.net.*; 
public class Server 
{ 

    public static void main(String[] args) throws Exception 
    { 
     ServerSocket ss = new ServerSocket(7948); 
     Socket s= ss.accept(); 
     System.out.print("Server connected\n"); 

     BufferedInputStream bis = new BufferedInputStream (s.getInputStream()); 
     BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream()); 

     while(true) 
     { 
      int a = bis.available(); 
      byte b[] = new byte[a]; 
      bis.read(b); 
      String str = new String(b); 
      str = str.toUpperCase(); 
      b = str.getBytes(); 
      bos.write(b,0,b.length); 
      bos.flush(); 

      if(str.equals("BYE")) 
       break; 
      else 
       continue; 
     } 
     System.out.print("\nServer Disconnecting"); 
     String str = "Adios Amigo"; 
     bos.write(str.getBytes()); 
     bos.flush(); 

     bis.close(); 
     bos.close(); 
     ss.close(); 
     s.close(); 
    } 
} 

Client.java:

import java.io.*; 
import java.net.*; 
public class Client 
{ 

    public static void main(String[] args) throws Exception 
    { 
     BufferedReader clientStream = new BufferedReader(new InputStreamReader(System.in)); 
     String str; 
     int a; 
     byte[] b; 

     Socket s = new Socket(InetAddress.getLocalHost(), 7948); 

     BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream()); 
     BufferedInputStream bis = new BufferedInputStream (s.getInputStream()); 

     one:while(true) 
     { 
      str = clientStream.readLine(); 
      b =str.getBytes(); 
      bos.write(b); 
      bos.flush(); 

      a=bis.available(); 
      b = new byte[a]; 
      bis.read(b); 
      str = new String (b); 
      str.trim(); 
      System.out.print("The server says: "+str); 
      if (str.equals("BYE")) 
      { 
       bis.read(b); 
       str = new String (b); 
       System.out.print("The server says: "+str); 
       break one; 
      } 
     } 

     s.close(); 
     clientStream.close(); 
     bos.close(); 
     bis.close(); 
    } 
} 

該方案是除了一個問題正常工作,在客戶端側的輸出來的兩個輸入之後。這意味着我必須提供來自客戶端的兩個輸入以獲得第一個輸出,並且這繼續。我無法跟蹤該錯誤。 任何人都可以請幫忙嗎?

回答

3

在客戶端,您發送數據到服務器,然後立即呼叫a.available() - 此功能不會等待從服務器發送數據。由於調用.available()時服務器不太可能用數據做出響應,函數返回零。

因此,您的字節數組b(請在將來使用更多的描述性變量名稱)長度爲零。

一旦創建了大小爲零的數組,您最終通過調用bis.read()來等待數據 - .read()是一個阻塞調用。它會等待來自服務器的數據。這個數據實際上沒有讀取,因爲你正在讀取的數組大小爲零。這會導致打印出空字符串。

下面的代碼將解決這個問題,但對於未來,我不建議使用.available()--這在我的經驗中是相當不可靠的。您應該通過簡化嘗試讀取數據來檢查數據是否可用。

Client.java:

one:while(true) 
    { 
     str = clientStream.readLine(); 
     b =str.getBytes(); 
     bos.write(b); 
     bos.flush(); 

     while (bis.available() <= 0) 
     { 
      // wait for data! 
     } 

     a=bis.available(); 
     b = new byte[a]; 
     bis.read(b); 
     str = new String (b); 
     str.trim(); 
     System.out.print("The server says: "+str); 
     if (str.equals("BYE")) 
     { 
      bis.read(b); 
      str = new String (b); 
      System.out.print("The server says: "+str); 
      break one; 
     } 
    } 
+0

感謝亞歷克斯 我會記住你的建議,而在未來的變量命名:) – Rajat 2013-03-02 08:23:52