2011-04-25 54 views
0

服務器客戶端服務器程序在循環後卡住?

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 

import javax.print.PrintService; 
import javax.print.PrintServiceLookup; 


public class GetFileServer implements Runnable { 

    public static final int SERVERPORT = 4444; 
    public String FileName=null; 
    public void run() { 
     try { 
      ServerSocket svr=new ServerSocket(SERVERPORT); 
      while(true){ 
       System.out.println("S: Waiting..."); 

       Socket sktClient=svr.accept(); 
       System.out.println("S: Receiving..."); 
       try{ 

        PrintService services[] = 
         PrintServiceLookup.lookupPrintServices(null, null); 

        PrintWriter out2 = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sktClient.getOutputStream())),true); 

        for(int z=0;z<services.length;z++){ 

         out2.println(services[z]); 
        } 

        //Get All Required Strings 
        InputStream inStream = sktClient.getInputStream(); 
        BufferedReader inm = new BufferedReader(new InputStreamReader(inStream)); 
        String fileName = inm.readLine(); 


        //Read, and write the file to the socket 
        BufferedInputStream in = new BufferedInputStream(sktClient.getInputStream());   
        int i=0;      
        File f=new File("D:/data/"+fileName); 
        if(!f.exists()){ 
         f.createNewFile(); 
        } 
        FileOutputStream fos = new FileOutputStream("D:/data/"+fileName); 
        BufferedOutputStream out = new BufferedOutputStream(fos); 

        while ((i = in.read()) != -1) { 
         System.out.println(i); 
         out.write(i); 
         System.out.println("Receiving data..."); 
        } 

        out.flush(); 
        in.close(); 
        out.close(); 
        sktClient.close();   
        System.out.println("Transfer complete."); 

       File inp = new File("D:/data/"+fileName); 
      // PrintFile.fileToPrint(inp); 
       } 
       catch(Exception e){ 

        e.printStackTrace(); 
       } 
      } 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String [] args){ 

     Thread servThread =new Thread(new GetFileServer()); 
     servThread.start(); 
    } 
} 

客戶端獲取到的打印機列表中While循環在客戶端??爲什麼呢?當我停止服務器progarm代碼運行滿後

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.util.ArrayList; 


public class Client implements Runnable { 
    static final int PORT = 4444; //Change this to the relevant port 
    static final String HOST = "192.168.0.53"; //Change this to the relevant HOST,//(where Server.java is running) 

    public void run() { 

     try { 
      System.out.print("Sending data...\n"); 
      Socket skt = new Socket(HOST, PORT); 

      File fil=new File("D:/a.txt"); 
      String FileName=fil.getName(); 

      //Send required data Strings to Server 
      PrintWriter out2 = new PrintWriter(new BufferedWriter(new OutputStreamWriter(skt.getOutputStream())),true); 
      out2.println(FileName);   

      ArrayList Printers =new ArrayList(); 
      InputStream inStream = skt.getInputStream(); 
      BufferedReader inm = new BufferedReader(new InputStreamReader(inStream)); 

      while ((inm.read()) != -1) { 
       Printers.add(inm.readLine()); 

      } 
      //Create a file input stream and a buffered input stream. 
      FileInputStream fis = new FileInputStream(fil); 
      BufferedInputStream in = new BufferedInputStream(fis); 
      BufferedOutputStream out = new BufferedOutputStream(skt.getOutputStream()); 

      //Read, and write the file to the socket    
      int i; 
      while ((i = in.read()) != -1) { 
       out.write(i); 
       System.out.println(i); 
      } 

      //Close the socket and the file 
      out.flush(); 
      out.close(); 
      in.close(); 
      skt.close(); 

     } 
     catch(Exception e) {   
      System.out.print("Error! It didn't work! " + e + "\n"); 
     } 
    } 

    public static void main(String [] args){ 

     Thread cThread =new Thread(new Client()); 
     cThread.start(); 
    } 
} 

代碼停止。

回答

1

可能是因爲您沒有在服務器端關閉out2寫入器(或刷新),剛剛在out2.println(services[z]);週期之後。

作者不會在將數據傳遞給他時立即發送數據,而是緩存數據並等待適當的時刻發送數據。然後服務器等待來自客戶端的輸入,並且你會得到一種死鎖。

+0

Thks !!! it workd !! – Harinder 2011-04-25 13:27:56

3

您的客戶端從服務器讀取數據,直到流在第一個while循環中關閉。由於你的服務器永遠不會關閉流,即使服務器不再說任何東西,客戶端仍會繼續嘗試和閱讀。因此,讀取的呼叫只是永遠等待。

您可能需要關閉服務器端的流,或者從服務器向客戶端發送一些字符串,表明它現在已經發送了完整的打印機列表 - 換句話說,一些控制字符串如「END」或者其他的東西。

更好的是,客戶端和服務器之間的通信仍然是異步的,所以你不會在它們之間產生這種類型的依賴關係,這會導致這些類似死鎖的問題。