收到时,Java发送文件总是少8个字节

时间:2015-01-25 01:59:00

标签: java sockets

我的java服务器 - 客户端文件通信存在两个问题,

我让CLIENT将文件发送到服务器,SERVER接收文件。

我的两个问题是:

1)每当我发送文件时,它减少8个字节(我不知道为什么)

2)文件传输不完整(少8个字节),除非我关闭套接字,这是我不想要的。我希望我的连接是持久的,所以我如何从客户端向服务器发送EOF。

这是我发送文件的客户

public void sendFiles(String file)  {
        try {
            File myFile = new File(file);

            long length = myFile.length();

            byte[] buffer = new byte[8192];
            System.out.println(length);

            FileInputStream in = new FileInputStream(myFile);
            BufferedInputStream bis = new BufferedInputStream(in);
            BufferedOutputStream outF = new BufferedOutputStream(sock.getOutputStream());

            out.print("%SF%" + length + "$" + myFile.getName() + "#");
            out.flush();

            int count;
            while ((count = in.read(buffer)) > 0) {
                outF.write(buffer, 0, count);
            }

            outF.flush();
            in.close();
            bis.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
}

接收文件的服务器。

我传递了文件的名称和长度,但只使用了文件的名称。但是,我不知道我是否需要使用文件的长度,如果是EOF或其他东西。请建议

此外,代码挂起

while ((count = this.sock.getInputStream().read(buffer)) > 0) {

由于没有EOF,我不知道如何实施

public void recvFile(String fileName, int length) {

try {
    byte[] buffer = new byte[8192];

    FileOutputStream outF = new FileOutputStream("/Users/Documents" +fileName);
    BufferedOutputStream bos = new BufferedOutputStream(outF);

    int count = length;
    while ((count = this.sock.getInputStream().read(buffer)) > 0) {
        bos.write(buffer, 0, count);
    }
    bos.close();

} catch (IOException ex) {
    ex.printStackTrace();
}
}

更新:我已经删除了flush(),因为它不需要它。此外,我已经在另一个类中测试了这个代码并且它有效,但它在这里与客户端 - 服务器聊天无关。谁能告诉我为什么?

任何帮助或提示将不胜感激。 谢谢。

2 个答案:

答案 0 :(得分:1)

我建议您首先发送文件大小和/或文件的属性...您可以尝试HTTP,这是广泛用于此任务... 另一个建议是你在其他TCP端口上打开另一个连接只是为了发送文件(这实际上是FTP发送文件的方式)

答案 1 :(得分:0)

我怀疑你遇到的问题是你没有出现的代码。

在此示例中,您可以通过同一个流发送多个消息或文件。

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.SocketChannel;

/**
 * Created by peter on 1/25/15.
 */
public class DataSocket implements Closeable {
    private final Socket socket;
    private final DataOutputStream out;
    private final DataInputStream in;

    public DataSocket(Socket socket) throws IOException {
        this.socket = socket;
        this.out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
        this.in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
    }

    @Override
    public void close() throws IOException {
        out.flush();
        socket.close();
    }

    // message format is length as UTF-8 encoded name, 32-bit int followed by data.
    public void writeMessage(String description, byte[] bytes) throws IOException {
        out.writeUTF(description);
        out.writeInt(bytes.length);
        out.write(bytes);
        out.flush();
    }

    public byte[] readMessage(String[] description) throws IOException {
        description[0] = in.readUTF();
        int length = in.readInt();
        byte[] bytes = new byte[length];
        in.readFully(bytes);
        return bytes;
    }

    public void writeFile(File file) throws IOException {
        long length = file.length();
        if (length > Integer.MAX_VALUE) throw new IllegalArgumentException("length=" + length);
        out.writeUTF(file.toString());
        out.writeInt((int) length);
        byte[] buffer = new byte[(int) Math.min(length, 32 * 1024)];
        try (FileInputStream fis = new FileInputStream(file)) {
            for (int len; (len = fis.read(buffer)) > 0; ) {
                out.write(buffer, 0, len);
            }
        }
        out.flush();
    }

    public void readFile(File dir) throws IOException {
        String fileName = in.readUTF();
        int length = in.readInt();
        byte[] buffer = new byte[(int) Math.min(length, 32 * 1024)];
        try (FileOutputStream fos = new FileOutputStream(new File(dir, fileName))) {
            while (length > 0) {
                int len = in.read(buffer);
                fos.write(buffer, 0, len);
                length -= len;
            }
        }
    }

    // todo convert to a unit test
    public static void main(String[] args) throws IOException {
        // port 0 opens on a random free port.
        ServerSocket sc = new ServerSocket(0);
        DataSocket ds1 = new DataSocket(new Socket("localhost", sc.getLocalPort()));
        DataSocket ds2 = new DataSocket(sc.accept());
        sc.close();
        // now ds1 and ds2 are connected.
        File f = File.createTempFile("deleteme","");
        f.deleteOnExit();
        try (FileOutputStream fos = new FileOutputStream(f)) {
            fos.write(new byte[10001]);
        }
        // send a request
        ds1.writeMessage("Send me the file", new byte[0]);
        String[] desc = { null };
        byte[] data = ds2.readMessage(desc);
        if (!desc[0].equals("Send me the file")) throw new AssertionError();
    // return a response
        ds2.writeFile(f);
        f.delete();
        if (f.exists()) throw new AssertionError();
        ds1.readFile(new File(""));
        if (f.length() != 10001) throw new AssertionError("length="+f.length());
        ds1.close();
        ds2.close();
        System.out.println("Copied a "+f.length()+" file over TCP");
    }
}