So I have been working with sockets a bit in the past few days, and tried to make a basic program to transfer files. The files do transfer, but they are incomplete. Like, when I try to send a 500kB file, the receiver only gets a 480kB one. I searched for quite a while but I just cant find the error. I found on some similar errors that the streams werent closed, but mine is, and it still doesnt send properly.

Sender:

//Main
//...
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
//...

public void sendFile(File file)
{
    try {           
        buffer = new byte[(int) file.length()];
        DataInputStream filestream = new DataInputStream(new FileInputStream(file));
        filestream.readFully(buffer);

        DataOutputStream outStream = new DataOutputStream(socket.getOutputStream());

        send("FILE_"+file.length()+"_\t"+file.getName());

        outStream.write(buffer);
        outStream.flush();

        filestream.close();

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

public void send(String data) {
    out.println(data);
}

Receiver:

DataInputStream inStream = new DataInputStream(client.getInputStream());

File file = new File("temp"+"\\"+expectedFile);
file.createNewFile();

BufferedOutputStream fileOut = new BufferedOutputStream(new FileOutputStream(file, false));

buffer = new byte[1024];

while (size > 0 && (receivedBytes = inStream.read(buffer, 0, (int)Math.min(buffer.length, size))) != -1)     
{     
    fileOut.write(buffer, 0, receivedBytes);
    fileOut.flush();     
    size -= receivedBytes;     
}  

fileOut.close(); 

Thanks for any kind of help :)

有帮助吗?

解决方案

You drop the first read of data on the floor in this line:

int receivedBytes = inStream.read(buffer, 0, buffer.length);

Not really sure what that line of code is for (old debugging?). You basically just need to remove it.

UPDATE:

You seem to indicate that you are sending additional metadata at the beginning of the stream. My guess is that you are using some sort of BufferedInputStream/Reader when reading the initial metadata, and that is swallowing part of the subsequent file data.

You can somewhat solve this problem by wrapping the DataInputStream around the BufferedInputStream you are using to read the metadata. You have to be careful, however, that whatever you are using to read the metadata doesn't read more data than it should. It's actually trickier to do this than you might think. You might want to look at using the DataInput/Output streams exclusively (use writeUTF/readUTF to handle the file name and writeLong/readLong to handle the file size).

其他提示

receiving end in general should look something like this...

socket = serverSocket.accept();
socket is = socket.getInputStream();

FileOutputStream fos = new FileOutputStream("fileName");
BufferedOutputStream bos = new BufferedOutputStream(fos);

int count;
while ((count = is.read(bytes)) > 0) {
        bos.write(bytes, 0, count);
    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top