Sending files through sockets

2020-02-05 06:15发布

问题:

Hello there im trying to send files using client-server classes in java. For some reason when the method that sends the file is called the socket closes. here is the code :

FileInputStream fIn = new FileInputStream(file);
out = new BufferedOutputStream(clientSocket.getOutputStream());
byte fileContent[] = new byte[(int) file.length()];
fIn.read(fileContent);
for (byte b : fileContent) {
    out.write(b);
}

and the code from the client :

FileOutputStream fIn = new FileOutputStream("testing");
BufferedInputStream inAout = new BufferedInputStream(clientSocket.getInputStream());
byte fileContent[] = new byte[1000000];
inAout.read(fileContent);
fIn.write(fileContent);

and the error message i get : SEVERE: null java.net.SocketException: Socket closed

Im not really experienced with this so if any can help it would be great.

回答1:

The InputStream.read(byte[]) method returns an int for the number of bytes it actually read. It's not guaranteed to read as many bytes as you requested from the byte array. It'll often return the size of the underlying buffer and you'll have to call it many times.

You can use this to be more efficient by streaming the bytes from the socket to the file instead of buffering the whole byte array in memory. Likewise on the server side you can do the same thing to save memory and be faster than writing a byte at a time.

Here's a working example of a server and client in one that connects to itself to transfer a file:

public class SocketFileExample {
    static void server() throws IOException {
        ServerSocket ss = new ServerSocket(3434);
        Socket socket = ss.accept();
        InputStream in = new FileInputStream("send.jpg");
        OutputStream out = socket.getOutputStream();
        copy(in, out);
        out.close();
        in.close();
    }

    static void client() throws IOException {
        Socket socket = new Socket("localhost", 3434);
        InputStream in = socket.getInputStream();
        OutputStream out = new FileOutputStream("recv.jpg");
        copy(in, out);
        out.close();
        in.close();
    }

    static void copy(InputStream in, OutputStream out) throws IOException {
        byte[] buf = new byte[8192];
        int len = 0;
        while ((len = in.read(buf)) != -1) {
            out.write(buf, 0, len);
        }
    }

    public static void main(String[] args) throws IOException {
        new Thread() {
            public void run() {
                try {
                    server();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

        client();
    }
}


回答2:

The reason is pretty simple: The call inAout.read(fileContent) will return after about 4KB of data has been transmitted. That's the input buffer size. So instead of a single huge read, you need a loop and many reads and write as many bytes to fIn as you got from the socket.

Also don't forget to flush the output on the server side (closing will flush it) or some data will be lost.



回答3:

SEVERE: null java.net.SocketException: Socket closed

That means you've closed the socket yourself and then called another operation that needs it open. For example, closing the socket or its input stream or output stream closes the other stream and the socket. Somewhere or other you are doing that.