2015-05-24 166 views
0

在我的客户端服务器应用程序中,它能够接收命令并返回结果。当我尝试从服务器端下载文件时发生此问题。进入下载命令后,服务器提示显示了这个错误,如何以适当的方式关闭OutputStream?

java.net.SocketException: socket closed 

图片:

Image

否则编程工作正常,也是它能够将文件下载到客户端。

注意我可能的原因是关于outputSteram的关闭(在我的ServerSide项目中),这可能没有以正确的方式完成。

我的完整的工作代码:

服务器端:

public class ServerSide { 

    private BufferedReader inputFromClient; 
    private PrintWriter outputToClient; 
    private FileInputStream fis; 
    private OutputStream os; 
    private static final int PORT = 8000; 
    private ServerSocket serverSocket; 
    private Socket socket; 

    public static void main(String[] args) { 
     int port = PORT; 
     if (args.length == 1) { 
      port = Integer.parseInt(args[0]); 
     } 
     new ServerSide(port); 
    } 

    private boolean fileExists(File[] files, String filename) { 
     boolean exists = false; 
     for (File file : files) { 
      if (filename.equals(file.getName())) { 
       exists = true; 
      } 
     } 
     return exists; 
    } 

    public ServerSide(int port) { 
     // create a server socket 
     try { 
      serverSocket = new ServerSocket(port); 
     } catch (IOException ex) { 
      System.out.println("Error in server socket creation."); 
      System.exit(1); 
     } 

     while (true) { 
      try { 

       socket = serverSocket.accept(); 
       outputToClient = new PrintWriter(socket.getOutputStream()); 
       inputFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

       while (true) { 

        String request = inputFromClient.readLine(); 

        if (!request.startsWith("exit") && !request.startsWith("pwd") && !request.startsWith("list") && !request.startsWith("GET")) { 
         outputToClient.println("Wrong request\r\n" 
           + "\r\n"); 
        } else if (request.startsWith("exit")) { 
         break; 
        } else if (request.startsWith("pwd")) { 
         File file = new File(System.getProperty("user.dir")); 
         outputToClient.print("Status OK\r\n" 
           + "Lines 1\r\n" 
           + "\r\n" 
           + "Working dir: " + file.getName() + "\r\n"); 
        } else if (request.startsWith("list")) { 
         File file = new File(System.getProperty("user.dir")); 
         File[] files = file.listFiles(); 
         outputToClient.print("Status OK\r\n" 
           + "Files " + files.length + "\r\n" 
           + "\r\n" 
           + Arrays.toString(files).substring(1, Arrays.toString(files).length() - 1) + "\r\n"); 
        } else if (request.startsWith("GET")) { 
         String filename = request.substring(4); 
         File file = new File(System.getProperty("user.dir")); 
         File[] files = file.listFiles(); 

         if (fileExists(files, filename)) { 
          file = new File(filename); 
          int fileSize = (int) file.length(); 

          outputToClient.printf("Status OK\r\nSize %d Bytes\r\n\r\nFile %s Download was successfully\r\n", 
            fileSize, filename); 
          outputToClient.flush(); 

          try (FileInputStream fis = new FileInputStream(file)) { 
           os = socket.getOutputStream(); 
           byte[] buffer = new byte[(1 << 7) - 1]; 
           int bytesRead = 0; 

           while ((bytesRead = fis.read(buffer)) != -1) { 
            os.write(buffer, 0, bytesRead); 
           } 

          } 
          os.close();//the problem probably occurs here. 
          // fis.close(); 
         } else { 
          outputToClient.print("Status 400\r\n" 
            + "File " + filename + " not found\r\n" 
            + "\r\n"); 
          outputToClient.flush(); 
         } 
        } 
        outputToClient.flush(); 
       } 
      } catch (IOException e) { 
       System.err.println(e); 
      } 

     } 
    } 
} 

客户方:

public class ClientSide { 

    private static Socket socket; 
    private static PrintWriter outputToServer; 
    private static BufferedReader inputFromServer; 
    private static InputStream is; 
    private static FileOutputStream fos; 
    private static final int PORT = 8000; 
    private static final String SERVER = "85.197.159.45"; 
    boolean Connected; 
    DataInputStream serverInput; 

    public static void main(String[] args) throws InterruptedException { 
     String server = "localhost"; 
     int port = PORT; 

     if (args.length >= 1) { 
      server = args[0]; 
     } 
     if (args.length >= 2) { 
      port = Integer.parseInt(args[1]); 
     } 

     new ClientSide(server, port); 
    } 

    public ClientSide(String server, int port) { 

     try { 
      socket = new Socket(server, port); 
      serverInput = new DataInputStream(socket.getInputStream()); 
      outputToServer = new PrintWriter(socket.getOutputStream(), true); 
      inputFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      System.out.println("Client is connected! "); 
      Connected = true; 
      String line = null; 

      Scanner sc = new Scanner(System.in); 
      System.out.print("Type command: "); 

      while (sc.hasNextLine()) { 
       String request = sc.nextLine(); 

       if (request.startsWith("exit")) { 
        outputToServer.println(request); 
        System.out.println("Application exited!"); 
        //outputToServer.flush(); 
        break; 
       } else if (request.startsWith("pwd")) { 
        outputToServer.println(request); 
        outputToServer.flush(); 
       } else if (request.startsWith("list")) { 
        outputToServer.println(request); 
        outputToServer.flush(); 
       } else if (request.startsWith("GET")) { 
        System.out.print("\r\n"); 
        outputToServer.println(request); 
        outputToServer.flush(); 
       } 
       while (Connected) { 
        line = inputFromServer.readLine(); 
        System.out.println(line); 
        if (line.isEmpty()) { 
         Connected = false; 
         if (inputFromServer.ready()) { 
          System.out.println(inputFromServer.readLine()); 
         } 
        } 
        if (line.startsWith("Status 400")) { 
         while (!(line = inputFromServer.readLine()).isEmpty()) { 
          System.out.println(line); 
         } 
         break; 
        } 
        if (request.startsWith("GET")) { 
         File file = new File(request.substring(4)); 
         is = socket.getInputStream(); 
         fos = new FileOutputStream(file); 

         byte[] buffer = new byte[socket.getReceiveBufferSize()]; 
         serverInput = new DataInputStream(socket.getInputStream()); 
         //int bytesReceived = 0; 
         byte[] inputByte = new byte[4000]; 

         int length; 
         while ((length = serverInput.read(inputByte, 0, inputByte.length)) > 0) { 
          fos.write(inputByte, 0, length); 

         } 

         /* 
         while ((bytesReceived = is.read(buffer)) >=0) { 
         //while ((bytesReceived = is.read(buffer))>=buffer) { 
         fos.write(buffer, 0, bytesReceived); 
         } 
         */ 
         request = ""; 
         fos.close(); 
         is.close(); 
        } 
       } 
       System.out.print("\nType command: "); 
       Connected = true; 
      } 
      outputToServer.close(); 
      inputFromServer.close(); 
      socket.close(); 
     } catch (IOException e) { 
      System.err.println(e); 
     } 

    } 
} 

回答

1

问题结束后,我想,是在该命令处理之后(GET )您正在关闭服务器套接字中的那个os.close()调用。意识到osoutputToClientinputFromClient取决于相同的服务器套接字。因此,在关闭os时,您正在影响其他两个流。然后,在服务GET请求之后,服务器循环会开始并尝试运行inputFromClient.readLine(),但底层套接字已关闭。

+0

谢谢。我尝试过不同的方式来解决它。因此我需要知道如何在编码中实现它。 – Munira

+0

我看到你在发送GET时也在客户端代码中运行is.close()。我的建议是:在客户端注释该行,并在服务器中使用os.close()。 –

0

服务器被写入插座,完成后其关闭套接字客户端收到有机会完成下载/读取它。您可以改为使其一旦完成读取/下载,就会向服务器发送消息以关闭套接字。

+0

阿修罗,谢谢,但我其实已经研究了这么多关于这个问题的理论解释。我应用了这些,并没有奏效。请你具体说明一下,在我的编码中如何实现? – Munira

0

try-with-resources语句是声明一个或多个资源的try语句。资源是程序结束后必须关闭的对象。 try-with-resources语句确保每个资源在语句结束时都关闭。任何实现java.lang.AutoCloseable的对象(包含所有实现java.io.Closeable的对象)都可以用作资源。

try(DataOutputStream out= new DataOutputStream(newFileOutputStream("data"))) 
{ 
     out.writeInt(666); 
} 

或者,你可以利用的finally块来关闭流你使用它

try 
{ 
    DataOutputStream out= new DataOutputStream(newFileOutputStream("data"); 
    out.writeInt(666); 
} 
catch(Exception e) 
{ 
    e.printStackTrace(); 
} 
finally 
{ 
    if(out != null) 
    { 
     out.close(); 
    } 
} 
+0

艾伦,谢谢。但是,你可以看到我有两个“尝试”块。 Ater哪个try-catch块我需要添加“finally”块。 – Munira

相关问题