2013-09-26 31 views
2

如何在Java套接字编程中实现从客户端到服务器的持续交互。在我的程序中,我有一个目录中的许多文件夹ie)F://读取并且我将文件从客户端传输到服务器。当第一次请求时,一个文件夹从客户端传输到服务器,当它再次到客户端发送另一个文件夹时,它会一直说异常,java.net.SocketException:在ClientProgram的write()方法中关闭Socket我打电话给socket.getOutputStream()。所以请告诉我如何解决这个问题。我想我想为每次传输使用线程,所以请告诉我必须在哪里运行这个罚款。十分感谢。如何在Java套接字编程中实现从客户端到服务器的持续交互

客户端代码:

在每个时间向前方法和写方法传递数据的从客户端到服务器。和listf(String directoryName)方法递归地运行文件和文件夹,当它发现文件夹时它调用的forward()和write()方法。 forward()用于传递特定文件夹的目录路径,write()方法用于在客户端写入所有文件,并且每次都通过listf(String directoryName)传递给服务器。在第一次这种方法运行良好。当第二次再次调用write()方法时,在那里给出java.net.SocketException:Socket被关闭,为什么它发生。

import java.io.*; 
import java.net.*; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
import java.util.ListIterator; 
import java.io.IOException; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

public class ClientProgram extends HttpServlet { 

    private static final long serialVersionUID = 1L; 

    public ClientProgram() { 
     super(); 
    } 
    Socket socket; 
    ClientProgram clientProgram; 
    String hostDomain = "192.168.1.19"; 
    int port = 5855; 
    BufferedOutputStream bos; 
    DataOutputStream dos; 
    BufferedInputStream bis; 
    FileInputStream fis; 
    PrintStream pr; 
    BufferedReader gt; 
    List<File> resultList; 

    public static listf(String directoryName) throws IOException { 
     try { 
      File directory = new File(directoryName); 
      resultList = new ArrayList<File>(); 
      // get all the files from a directory 
      File[] fList = directory.listFiles(); 
      resultList.addAll(Arrays.asList(fList)); 
      for (File file : fList) { 
       if (file.isFile()) { 
        System.out.println("file: " + file.getAbsolutePath()); 
       } else if (file.isDirectory()) { 
        String pathtomake = file.getAbsolutePath(); 
        System.out.println("folder now: " + pathtomake); 
        forward(pathtomake); 
        write(pathtomake); 
        System.out.println("folder: " + file.getAbsolutePath()); 
        listf(file.getAbsolutePath()); 

       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (bis != null) { 
       bis.close(); 
      } 
      if (dos != null) { 
       dos.close(); 
      } 
      if (fis != null) { 
       fis.close(); 
      } 
     } 
     return resultList; 
    } 

    public void write(String rec) throws IOException { 
     try { 
      System.out.println("rr"); 
      bos = new BufferedOutputStream(socket.getOutputStream()); 
      dos = new DataOutputStream(bos); 
      File file1 = new File(rec); 
      File[] fil_Files_list = file1.listFiles(); 
      dos.writeInt(fil_Files_list.length); 
      System.out.println("file will .."); 
      for (File file : fil_Files_list) { 
       long length = file.length(); 
       dos.writeLong(length); 
       String name = file.getName(); 
       dos.writeUTF(name); 
       fis = new FileInputStream(file); 
       bis = new BufferedInputStream(fis); 
       System.out.println("writin.."); 
       int theByte = 0; 
       while ((theByte = bis.read()) != -1) { 
        bos.write(theByte); 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
     } 
    } 

    public void forward(String drc) throws UnknownHostException, IOException { 
     boolean b = socket.isConnected(); 
     System.out.println("Socket Is active or not: " + b); 
     pr = new PrintStream(socket.getOutputStream()); 
     pr.println(drc); 
     gt = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     String tm = gt.readLine(); 
     System.out.print(tm); 
    } 

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     socket = new Socket(hostDomain, port); 
     String directory = "F://read"; 
     listf(directory); 

    } 

} 

服务器代码:

这是我的服务器代码接受与文件夹接收。在这里我正在接收文件夹路径使用客户端方法称为forward()并添加到detination路径即缓冲区读取器)d://保存。之后,我将所有文件写入客户端方法write()中的特定文件夹。

import java.io.*; 
import java.net.*; 
import java.io.IOException; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

public class ServerProgram extends HttpServlet { 

    private static final long serialVersionUID = 1L; 

    public ServerProgram() { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 

    BufferedReader ed; 
    PrintStream pr; 
    BufferedInputStream bis; 
    DataInputStream dis; 
    FileOutputStream fos; 
    BufferedOutputStream bos; 
    Socket socket; 

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     try { 
      System.out.println(1); 
      ServerSocket serverSocket = new ServerSocket(5792); 
      System.out.println(2); 
      socket = serverSocket.accept(); 

      ed = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      String tmp = ed.readLine(); 
      System.out.print("I Recieved :" + tmp); 
      pr = new PrintStream(socket.getOutputStream()); 
      String str = "Yup I got it !!"; 
      pr.println(str); 
      int g = tmp.indexOf("\\"); 
      String di = tmp.substring(g); 
      String dirPath = "D://save//" + di; 
      System.out.println(dirPath); 
      File file = new File(dirPath); 
      JavaHeapMemory(); 

      if (file.exists() || file.mkdirs()) { 
       bis = new BufferedInputStream(socket.getInputStream()); 
       dis = new DataInputStream(bis); 
       int filesCount = dis.readInt(); 
       File[] files = new File[filesCount]; 
       for (int i = 0; i < filesCount; i++) { 
        long fileLength = dis.readLong(); 
        String fileName = dis.readUTF(); 
        System.out.println("name of the file: " + fileName); 
        files[i] = new File(dirPath + "/" + fileName); 
        FileOutputStream fos = new FileOutputStream(files[i]); 
        BufferedOutputStream bos = new BufferedOutputStream(fos); 
        for (int j = 0; j < fileLength; j++) { 
         bos.write(bis.read()); 
        } 

       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (bos != null) { 
       bos.close(); 
      } 
      if (dis != null) { 
       dis.close(); 
      } 
      try { 
       socket.close(); 
      } catch (Exception e) { 
       // TODO: handle exception 
      } 
     } 
    } 

    public void JavaHeapMemory() { 
     long heapSize = Runtime.getRuntime().totalMemory(); 
     System.out.println("Heap Size = " + heapSize); 
    } 
} 

例外:

  java.net.SocketException: Socket is closed 
       at java.net.Socket.getOutputStream(Unknown Source) 
       at pack.ClientProgram.forward() 

在我用于文件夹递归传输到服务器此以上客户端程序。但它不是从客户端连续运行到服务器,所以请告诉我这样做的方法。我非常感谢。

回答

2

您可以混合文本和二进制文件,而不会产生混淆。

ed = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

这意味着BufferedReader可以读取尽可能多的数据,而不仅仅是要求多少。

bis = new BufferedInputStream(socket.getInputStream()); 

这将开始在一些随机点读取二进制的BufferedReader中没有读(不是你要的量)

总之,只有使用二进制或文本流,除非你真的知道你在做什么。


你的程序有

while ((theByte = bis.read()) != -1) 
     bos.write(theByte); 

这意味着,一直读到流的末尾。这也意味着它将读取连接关闭前发送的所有数据。

如果您想在同一个流中发送多个文件,则需要另一种方式让接收方知道文件何时结束。最简单的方法是首先发送文件大小,并让接收者只读取那么多数据。

BTW一次读取一个字节是非常慢很慢。我建议你读入大小为4KB的字节[]。

相关问题