Отправка файлов через сокеты - PullRequest
2 голосов
/ 23 мая 2011

Здравствуйте, я пытаюсь отправить файлы, используя классы клиент-сервер в Java. По какой-то причине, когда метод, который отправляет файл, называется сокетом, он закрывается. вот код:

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);
}

и код от клиента:

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

и сообщение об ошибке, которое я получаю: SEVERE: null java.net.SocketException: сокет закрыт

Я не очень разбираюсь в этом, так что если кто-нибудь может помочь, это было бы здорово.

Ответы [ 3 ]

14 голосов
/ 23 мая 2011

Метод InputStream.read(byte[]) возвращает int для количества байтов, которые он фактически прочитал.Не гарантируется чтение столько байтов, сколько вы запросили из байтового массива.Он часто будет возвращать размер базового буфера, и вам придется вызывать его много раз.

Вы можете использовать это для большей эффективности, передавая байты из сокета в файл вместо буферизациивесь массив байтов в памяти.Аналогично, на стороне сервера вы можете сделать то же самое, чтобы сэкономить память и быть быстрее, чем запись байта за раз.

Вот рабочий пример сервера и клиента в одном, который соединяется с собой для передачи файла:

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();
    }
}
0 голосов
/ 24 мая 2011
SEVERE: null java.net.SocketException: Socket closed

Это означает, что вы сами закрыли сокет, а затем вызвали другую операцию, которая требует его открытия. Например, закрытие сокета или его входного потока или выходного потока закрывает другой поток и сокет. Вы так или иначе делаете это.

0 голосов
/ 23 мая 2011

Причина довольно проста: вызов inAout.read(fileContent) будет возвращен после передачи около 4 КБ данных.Это размер входного буфера.Таким образом, вместо одного огромного чтения, вам нужен цикл и много операций чтения и записи в fIn столько байтов, сколько вы получили из сокета.

Также не забудьте сбросить вывод на стороне сервера(закрытие сбрасывает его) или некоторые данные будут потеряны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...