I trying to send a file between two computer using this code:

class FileSender :

import java.io.OutputStream;
import java.io.File;

import java.net.Socket;


public class FileSender {
    // host and port of receiver
    private static final int port = 4700;
    private static final String host = "localhost";

    public static void main(String[] args) {
        try {
            Socket socket = new Socket(host, port);
            OutputStream os = socket.getOutputStream();

            int cnt_files = 1;

            // How many files?
            ByteStream.toStream(os, cnt_files);

            for (int cur_file = 0; cur_file < cnt_files; cur_file++) {
                ByteStream.toStream(os, "test.txt");
                ByteStream.toStream(os, new File("test.txt"));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

Class FileReceiver:

import java.io.File;
import java.io.InputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class FileReceiver implements Runnable {

    private static final int port = 4700;

    private Socket socket;

    public static void main(String[] _) {
        try {
            ServerSocket listener = new ServerSocket(port);

            while (true) {
                FileReceiver file_rec = new FileReceiver();
                file_rec.socket = listener.accept();

                new Thread(file_rec).start();
            }
        } catch (java.lang.Exception ex) {
            ex.printStackTrace(System.out);
        }
    }

    public void run() {
        try {
            InputStream in = socket.getInputStream();

            int nof_files = ByteStream.toInt(in);

            for (int cur_file = 0; cur_file < nof_files; cur_file++) {
                String file_name = ByteStream.toString(in);
                StringTokenizer st = new StringTokenizer(file_name, "\\");
                ArrayList<String> strings = new ArrayList<String>();
                while (st.hasMoreElements()) {
                    strings.add(st.nextToken().toString());
                }
                System.out.println("c:\\Users\\acer5635\\Documents\\" + strings.get(0));
                File file = new File("c:\\Users\\acer5635\\Documents\\" + strings.get(0));
                ByteStream.toFile(in, file);
            }
        } catch (java.lang.Exception ex) {
            ex.printStackTrace(System.out);
        }
    }
}

class ByteStream:

import java.io.InputStream;
import java.io.OutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;

public class ByteStream {
    private static byte[] toByteArray(int in_int) {
        byte a[] = new byte[4];
        for (int i = 0; i < 4; i++) {

            int b_int = (in_int >> (i * 8)) & 255;
            byte b = (byte) (b_int);

            a[i] = b;
        }
        return a;
    }

    private static int toInt(byte[] byte_array_4) {
        int ret = 0;
        for (int i = 0; i < 4; i++) {
            int b = (int) byte_array_4[i];
            if (i < 3 && b < 0) {
                b = 256 + b;
            }
            ret += b << (i * 8);
        }
        return ret;
    }

    public static int toInt(InputStream in) throws java.io.IOException {
        byte[] byte_array_4 = new byte[4];

        byte_array_4[0] = (byte) in.read();
        byte_array_4[1] = (byte) in.read();
        byte_array_4[2] = (byte) in.read();
        byte_array_4[3] = (byte) in.read();

        return toInt(byte_array_4);
    }

    public static String toString(InputStream ins) throws java.io.IOException {
        int len = toInt(ins);
        return toString(ins, len);
    }

    private static String toString(InputStream ins, int len) throws java.io.IOException {
        String ret = new String();
        for (int i = 0; i < len; i++) {
            ret += (char) ins.read();
        }
        return ret;
    }

    public static void toStream(OutputStream os, int i) throws java.io.IOException {
        byte[] byte_array_4 = toByteArray(i);
        os.write(byte_array_4);
    }

    public static void toStream(OutputStream os, String s) throws java.io.IOException {
        int len_s = s.length();
        toStream(os, len_s);
        for (int i = 0; i < len_s; i++) {
            os.write((byte) s.charAt(i));
        }
        os.flush();
    }

    private static byte[] toByteArray(InputStream ins, int an_int) throws
            java.io.IOException,
            Exception {

        byte[] ret = new byte[an_int];

        int offset = 0;
        int numRead = 0;
        int outstanding = an_int;

        while ((offset < an_int)
                && ((numRead = ins.read(ret, offset, outstanding)) > 0)) {
            offset += numRead;
            outstanding = an_int - offset;
        }
        if (offset < ret.length) {
            throw new Exception("Could not completely read from stream, numRead=" 
                    + numRead + ", ret.length=" + ret.length); // ???
        }
        return ret;
    }

    private static void toFile(InputStream ins, FileOutputStream fos, int len, int buf_size) throws
            java.io.FileNotFoundException,
            java.io.IOException {

        byte[] buffer = new byte[buf_size];

        int len_read = 0;
        int total_len_read = 0;

        while (total_len_read + buf_size <= len) {
            len_read = ins.read(buffer);
            total_len_read += len_read;
            fos.write(buffer, 0, len_read);
        }

        if (total_len_read < len) {
            toFile(ins, fos, total_len_read, buf_size / 2);
        }
    }

    private static void toFile(InputStream ins, File file, int len) throws
            java.io.FileNotFoundException,
            java.io.IOException {

        FileOutputStream fos = new FileOutputStream(file);

        toFile(ins, fos, len, 1024);
    }

    public static void toFile(InputStream ins, File file) throws
            java.io.FileNotFoundException,
            java.io.IOException {

        int len = toInt(ins);
        toFile(ins, file, len);
    }

    public static void toStream(OutputStream os, File file)
            throws java.io.FileNotFoundException,
            java.io.IOException {

        toStream(os, (int) file.length());

        byte b[] = new byte[1024];
        InputStream is = new FileInputStream(file);
        int numRead = 0;

        while ((numRead = is.read(b)) > 0) {
            os.write(b, 0, numRead);
        }
        os.flush();
    }
}

I started FileReceiver first. In FileSende class, when I put host = "localhost"; the program worked fine. But when I tried to send a file from an other computer (I put host = "192.168.1.2" ==> IP from where I executed FileReceiver.java before I launched FileSende.java) I got this exception :

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at ByteStream.toInt(ByteStream.java:35)
    at ByteStream.toString(ByteStream.java:44)
    at FileReceiver.run(FileReceiver.java:41)
    at java.lang.Thread.run(Unknown Source)

The firewall in the two computer is turned off (the OS of both computer is windows 7 32bits.)

有帮助吗?

解决方案

You need to make sure that the File has been completely received by the receiver before you terminate your sender program.

You could let the receiver send an acknowledgement when it has received the file, and wait for that acknowledgement in the sender.

An easier way to achieve this in your case is to invoke Socket.shutdownOutput() after sending your file.

In your FileSender:

for (int cur_file = 0; cur_file < cnt_files; cur_file++) {
    ByteStream.toStream(os, "test.txt");
    ByteStream.toStream(os, new File("test.txt"));
}
socket.shutdownOutput();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top