2

如何在 Java 套接字编程中进行从客户端到服务器的持续交互。在我的程序中,我在一个目录中有很多文件夹,即)F://read,我正在将文件夹中的文件从客户端传输到服务器。当第一次请求时,一个文件夹从客户端传输到服务器,当它再次到客户端发送另一个文件夹时,它一直说异常,java.net.SocketException:Socket 在 ClientProgram 的 write() 方法中关闭,其中我调用 socket.getOutputStream()。所以请告诉我如何解决这个问题。我想我想为每次传输使用线程,所以请告诉我必须在哪里使用才能正常运行。非常感谢。

客户端代码:

每次转发方法和写入方法将数据从客户端传递到服务器。和 listf(String directoryName) 方法为文件和​​文件夹递归运行,当它找到文件夹时,它会调用 forward() 和 write() 方法。forward() 是传递特定文件夹的目录路径,write() 方法是将所有文件写入客户端,并每次通过 listf(String directoryName) 传递给服务器。第一次这种方法运行良好。当第二次再次调用 write() 方法时,它会给出 java.net.SocketException: Socket is closed.why 它发生的原因。

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);

    }

}

服务器代码:

这是我的服务器代码接受接收带有文件的文件夹。在这里,我使用 BufferedReader 从名为 forward() 的客户端方法接收文件夹路径,并添加到目标路径 ie)d://save。之后,我将所有文件从名为 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()

在上面的这个客户端程序中,我曾经递归地将文件夹传输到服务器。但它没有从客户端到服务器连续运行。所以请告诉我这样做的方法。我非常感谢。

4

1 回答 1

2

您不能在没有混淆的情况下混合文本和二进制文件。

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

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

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

这将在 BufferedReader 未读取的某个随机点开始读取二进制文件(不是您要求的数量)

简而言之,除非您真的知道自己在做什么,否则只能对流使用二进制或文本。


你的程序有

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

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

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

顺便说一句,一次读取一个字节非常慢。我建议你读入一个大小为 4KB 的字节 []。

于 2013-09-26T12:15:31.657 回答