【问题标题】:Socket gets Closed after 1st command套接字在第一个命令后关闭
【发布时间】:2014-02-19 23:38:27
【问题描述】:

我正在制作一个简单的 ftp 客户端/服务器程序,该程序根据客户端的命令列出文件,告诉当前目录,下载文件。

我想创建一个能够与多个客户端连接并且能够一次处理多个命令的服务器。我使用了线程,但我的代码在执行第一个命令后出现以下错误。

socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Myserver$Connecthandle.run(Myserver.java:123)
at Myserver.main(Myserver.java:35)
java.net.SocketException: socket closed

这是我的服务器代码:

public class Myserver {
static final int PortNumber = 120;
static ServerSocket MyService;
static Socket clientSocket = null;
/**
 * @param args
 * @throws IOException 
 */
public static void main(String[] args) throws IOException {
    File directory;
    directory = new File(System.getProperty("user.dir"));
     try {
           MyService = new ServerSocket(PortNumber);
           String cd = directory.toString();
           System.out.println(cd);
           System.out.println("Listening on " + PortNumber);
           while(true) {
           clientSocket = MyService.accept();
           Connecthandle a = new Connecthandle(clientSocket, directory);
           a.start();
           }
     }
     catch (IOException e) {
     System.out.println(e);
     }
}

     static class Connecthandle extends Thread {
         File Directory;
         Socket clientsocket;
         PrintWriter outgoing;

         // Constructor for class
         Connecthandle(Socket clients, File dir) {
             clientsocket = clients;
             Directory = dir;
         }

         // Works Fine
         void listfiles() throws IOException {
             String []Listfile = Directory.list();
             String send = "";
             for (int j = 0; j < Listfile.length; j++) {
                 send = send + Listfile[j] + ",";
             }
             DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
             GoingOut.writeBytes(send);
             GoingOut.flush();
             // GoingOut.close();
         }
         // Works Fine
         void currentdirectory() throws IOException {
             String cd = Directory.toString();
             String cdd = "resp," + cd;
             System.out.println(cdd);
             DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
             GoingOut.writeBytes(cdd);
             GoingOut.flush();
             GoingOut.close();
         }

         // Works fine
         void sendfiles(String fileName) {
             try {
             File nfile = new File(fileName);
             DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
             if ( (! nfile.exists()) || nfile.isDirectory() ) {
               GoingOut.writeBytes("file not present");
            } else {
             BufferedReader br = new BufferedReader(new FileReader(nfile));
             int coun = 0;
             String lin;
             while ((lin = br.readLine()) != null) {
                 coun++;
             }
             GoingOut.writeBytes("resp," + fileName + "," + String.valueOf(coun) + "\n");
             @SuppressWarnings("resource")
            BufferedReader sr = new BufferedReader(new FileReader(nfile));
             String line;
             while ((line = sr.readLine()) != null) {
                 GoingOut.writeBytes(line+"\n");
                 GoingOut.flush();
             }
             GoingOut.close();
             br.close();
            }
             } catch (IOException e) {
                 System.out.println("Unable to send!");
             }
         }

         public void start() {
             DataInputStream comingin = null;
            try {
                comingin = new DataInputStream(clientsocket.getInputStream());
            } catch (IOException e2) {
                e2.printStackTrace();
            }
             InputStreamReader isr = null;
            try {
                isr = new InputStreamReader(comingin, "UTF-8");
            } catch (UnsupportedEncodingException e1) {
                e1.printStackTrace();
            }
             BufferedReader br = new BufferedReader(isr);
             while (true) {
             try {
             String message = br.readLine(); 
             if (message.contains("pwd")) {
                 currentdirectory();
             } else if (message.contains("list")) {
                 listfiles();
             } else if (message.contains("get")) {
                 String fileName = new String(message.substring(8, message.length()));
                 sendfiles(fileName);
             } else if (message.contains("exit")) {
                 System.exit(0);
             }
             } catch (Exception e) {
                 e.printStackTrace();
             } finally {
                 try {
                    clientsocket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
             }
         }
     }

} 我将所有方法移到 start() 中,因此我只需要声明一次 dataoutputstream,但现在每当我使用 Outgoing.writeBytes 时它都会给出 NULLPOINTEREXCEPTION

更新:

    static class Connecthandle extends Thread {
         File Directory;
         Socket clientsocket;
         PrintWriter outgoing;

         // Constructor for class
         Connecthandle(Socket clients, File dir) {
             clientsocket = clients;
             Directory = dir;
         }

         public void run() {
             DataInputStream comingin = null;
            try {
                comingin = new DataInputStream(clientsocket.getInputStream());
            } catch (IOException e2) {
                e2.printStackTrace();
            }
             InputStreamReader isr = null;
            try {
                isr = new InputStreamReader(comingin, "UTF-8");
            } catch (UnsupportedEncodingException e1) {
                e1.printStackTrace();
            }
             BufferedReader br = new BufferedReader(isr);
             while (true) {
             try {
             String message = br.readLine(); 
             if (message.contains("pwd")) {
                 String cd = Directory.toString();
                 String cdd = "resp," + cd;
                 System.out.println(cdd);
                 DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
                 GoingOut.writeBytes(cdd);
                 GoingOut.flush();
             } else if (message.contains("list")) {
                 String []Listfile = Directory.list();
                 String send = "";
                 for (int j = 0; j < Listfile.length; j++) {
                     send = send + Listfile[j] + ",";
                 }
                 DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
                 GoingOut.writeBytes(send);
                 GoingOut.flush();
             } else if (message.contains("get")) {
                 String fileName = new String(message.substring(8, message.length()));
                 try {
                     File nfile = new File(fileName);
                     DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
                     if ( (! nfile.exists()) || nfile.isDirectory() ) {
                       GoingOut.writeBytes("file not present");
                    } else {
                     BufferedReader wr = new BufferedReader(new FileReader(nfile));
                     int coun = 0;
                     String lin;
                     while ((lin = wr.readLine()) != null) {
                         coun++;
                     }
                     GoingOut.writeBytes("resp," + fileName + "," + String.valueOf(coun) + "\n");
                     @SuppressWarnings("resource")
                    BufferedReader sr = new BufferedReader(new FileReader(nfile));
                     String line;
                     while ((line = sr.readLine()) != null) {
                         GoingOut.writeBytes(line+"\n");
                         GoingOut.flush();
                     }
                     GoingOut.close();
                     br.close();
             } 
                 } catch (IOException e) {
                     System.out.println("Unable to send!"); 
                 }
             } else if (message.contains("exit")) {
                 System.exit(0);
             }
             } catch (Exception e) {
                 e.printStackTrace();
             } finally {
                 try {
                    clientsocket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
             }
         }
     }
}

【问题讨论】:

  • 你不是在第一个命令后关闭套接字吗?
  • 你能告诉我在哪里吗?以及如何避免它?
  • clientsocket.close(); 在你的 finally 块中......我也不是 100%,但是关闭你从套接字获得的流也可能关闭套接字......
  • 我将 finally 块移出循环,但这并没有帮助。我相信正在发生的事情是,我在 sendfiles、listfiles 和当前目录中的 DataOutputStream 在调用该函数后关闭,该函数反过来也关闭了套接字,但是如果我不关闭我的输出流,那么我的代码就会挂起。
  • 我还尝试删除方法并将整个东西放在 start() 中,因为我必须只声明一次 GoingOut,但随后我的代码在 GoingOut.writeBytes(send); 行上给出了 NullPointerException

标签: java sockets networking ftp


【解决方案1】:

关闭一个套接字的输入流或输出流会关闭另一个流和套接字。在客户端断开连接或您超时之前,我不明白您为什么需要在这里关闭任何东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-20
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    相关资源
    最近更新 更多