1

我想通过套接字连接发送多个文件。对于一个文件,它可以完美运行,但是如果我尝试发送多个(一次一个),我会得到Socket Exception

java.net.SocketException:套接字关闭

一般来说,我的连接是这样的:

  1. 服务器等待连接
  2. 客户端连接到服务器并发送对某个文件的请求(包含文件名的字符串)
  3. 服务器读取本地文件并发送给客户端
  4. 客户端发送另一个文件的另一个请求并在第 3 点继续。

等待请求过程的运行方法如下所示:

@Override
public void run() {
    String message;
    try {
        while ((message = reader.readLine()) != null) {

            if (message.equals(REQUESTKEY)) {
                System.out.println("read files from directory and send back");
                sendStringToClient(createCodedDirContent(getFilesInDir(new File(DIR))), socket);
            } else if (message.startsWith(FILE_PREFIX)) {

                String filename = message.substring(FILE_PREFIX.length());
                try {
                    sendFile(new File(DIR + filename));
                } catch (IOException e) {
                    System.err.println("Error: Could not send File");
                    e.printStackTrace();
                }
            } else {
                System.out.println("Key unknown!");
            }
        }
    } catch (Exception ex) {

        ex.printStackTrace();
    }
}

我的sendFile()方法如下所示:

public void sendFile(File file) throws IOException {
    FileInputStream input = new FileInputStream(file);
    OutputStream socketOut = socket.getOutputStream();

    System.out.println(file.getAbsolutePath());
    int read = 0;
    while ((read = input.read()) != -1) {
        socketOut.write(read);
    }
    socketOut.flush();

    System.out.println("File successfully sent!");

    input.close();
    socketOut.close();
}

我认为问题出在socketOut.close(). 不幸的是,该方法也关闭了套接字连接(进一步连接的问题)。但是,如果我忽略此关闭,则文件传输将无法正常工作:文件到达客户端时不完整。

我怎样才能避免或解决这个问题?还是有更好的方法来传输多个请求的文件?

谢谢

4

2 回答 2

1

我已经稍微重写了您的发送文件方法,以便您可以发送多个文件,您需要在DataOutputStream发送完所有要发送的文件后传递它并关闭流。

读取时,您应该使用DataInputStreamand 调用long len = dis.getLong(),然后从流中读取len字节,然后重复下一个文件。您可能会发现在开始时发送文件数量很有用。

public void sendFile(File file, DataOutputStream dos) throws IOException {
    if(dos!=null&&file.exists()&&file.isFile())
    {
        FileInputStream input = new FileInputStream(file);
        dos.writeLong(file.getLength());
        System.out.println(file.getAbsolutePath());
        int read = 0;
        while ((read = input.read()) != -1)
            dos.writeByte(read);
        dos.flush();
        input.close();
        System.out.println("File successfully sent!");
    }
}
于 2013-08-01T17:34:30.350 回答
0

您可以在客户端和服务器之间定义一个简单的协议。在文件内容之前发送文件长度。使用 DataOutputStream / DataInputStream 发送/读取长度。不要在每个文件之后关闭套接字。

于 2013-08-01T15:59:19.520 回答