客户端服务器程序在循环后卡住了吗?

| 服务器
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();
    }
}
客户端
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();
    }
}
在客户端的While循环中获取打印机列表后,代码停止运行。为什么?当我停止服务器程序时,代码将运行满。     
已邀请:
可能是因为在循环使用
out2.println(services[z]);
之后,您没有关闭服务器端的
out2
编写器(或刷新)。 当您将数据传递给作家时,作家不会立即发送数据,而是会缓存数据并等待适当的时间发送。然后服务器等待来自客户端的输入,您会遇到某种僵局。     
您的客户端从服务器读取,直到在第一个while循环中关闭流为止。由于服务器永远不会关闭流,因此即使服务器不再说什么,客户端也将继续尝试读取。因此,阅读的呼叫将永远等待。 您要么需要关闭服务器端的流,要么将一些字符串从服务器发送到客户端,以表明它现在已经发送了打印机的完整列表,换句话说,就是一些控制字符串,例如\ “ END \”之类的。 最好还是使客户端和服务器之间的通信是异步的,这样您之间就不会有这种依赖关系,而这将导致这类类似死锁的问题。     

要回复问题请先登录注册