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

时间:2011-04-25 12:35:44

标签: java

服务器

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循环中获取打印机列表后代码停止在客户端?为什么?当我停止服务器程序时代码运行完毕。

2 个答案:

答案 0 :(得分:3)

您的客户端从服务器读取,直到第一个while循环中的流关闭。由于您的服务器永远不会关闭流,因此即使服务器不再说任何内容,客户端也会继续尝试读取。因此,read的调用只会永远等待。

您需要关闭服务器端的流,或者从服务器向服务器发送一些字符串,表明它现在已经发送了完整的打印机列表 - 换句话说,某些控制字符串如“END”或东西。

最好还是使客户端和服务器通信异步,这样你就不会有这些依赖关系,这会导致类似死锁的问题。

答案 1 :(得分:1)

可能是因为您没有在服务器端关闭out2编写器(或刷新),只是在out2.println(services[z]);循环之后。

当您将数据传递给他时,编写器不会立即发送数据,而是缓存数据并等待发送它的适当时刻。然后服务器等待来自客户端的输入,你会得到一种死锁。