powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблема при передаче файла между клиентом и сервером.
6 сообщений из 6, страница 1 из 1
Проблема при передаче файла между клиентом и сервером.
    #38826723
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет, подскажите, почему клиент при приеме файла от сервера недополучает несколько байт ?

Сервер:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
DataOutputStream dos = new DataOutputStream(client.getOutputStream());

...

                        for (String listNewFile : listNewFiles) {

                            String pathToFile = COBA_PATH_NAME + File.separator + listNewFile;
                            File sendFile = new File(pathToFile);
                            
                            //имя файла
                            out.println(listNewFile);
                            out.flush();

                            //размер файла
                            out.println(sendFile.length());
                            out.flush();

                            FileInputStream fis = new FileInputStream(sendFile);
                            BufferedInputStream bis = new BufferedInputStream(fis);

                            byte[] buffer = new byte[8 * 1024];
                            int count, total = 0;

                            while ((count = bis.read(buffer, 0, buffer.length)) != -1) {
                                total += count;
                                dos.write(buffer, 0, count);
                                dos.flush();

                                //по окончании все ок, total равен размеру файла: 131841 - 131841
                                System.out.println(total);
                            }

                            fis.close();
                            bis.close();
                        }




Клиент:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
DataInputStream dis = new DataInputStream(server.getInputStream());

...

                    for (int x = 0; x < filesCount; x++) {

                        String fileName = in.readLine();
                        String fileSize = in.readLine();

                        byte[] buffer = new byte[8 * 1024];
                        FileOutputStream fos = new FileOutputStream(COBA_PATH + File.separator + fileName);
                        BufferedOutputStream bos = new BufferedOutputStream(fos);

                        int count, total = 0;

                        while ((count = dis.read(buffer, 0, buffer.length)) != -1){
                            total += count;
                            bos.write(buffer, 0, count);
                            bos.flush();

                            //а вот тут уже все печально, все останавливается примерно на таких значениях: 128953 - 131841
                            Log.d(LOG_TAG, String.valueOf(total) + " - " + fileSize);

                            if(total == Long.parseLong(fileSize)){
                                break;
                            }
                        }
                        fos.close();
                        bos.close();
                    }


...
Рейтинг: 0 / 0
Проблема при передаче файла между клиентом и сервером.
    #38826730
maxkar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshun,

Кто такие in, out, dos и dis и как они связаны друг с другом?

Я ставлю на то, что ваш in читает в себя кусок файла, поэтому dis этого куска в последствии не хватает. Решение простое - не смешивать в одном потоке строковые и "текстовые" данные. А еще не конструировать разные обертки вокруг одного и того же inputstream. Только обертки внутри оберток, при этом везде использовать поток/обертку самого верхнего уровня.
...
Рейтинг: 0 / 0
Проблема при передаче файла между клиентом и сервером.
    #38826976
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мысль понял, спасибо.
...
Рейтинг: 0 / 0
Проблема при передаче файла между клиентом и сервером.
    #38827016
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал следующим образом, если кто-то прокомментирует на предмет рукожопости - был бы очень признателен.

Клиент:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
    private void update1() {

        try {

            InetAddress serverAddress = InetAddress.getByName(ADDRESS);
            Socket server = new Socket();
            Log.d(LOG_TAG, "Соединяемся ...");
            server.connect(new InetSocketAddress(serverAddress, PORT), CONNECTION_TIMEOUT);

            BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(server.getOutputStream())), true);

            out.println("getFilesNew:" + getLastUpdateDate());
            out.flush();
            Log.d(LOG_TAG, "Запрос новых файлов ...");

            int filesCount = Integer.parseInt(in.readLine());
            Log.d(LOG_TAG, "Новых файлов: " + filesCount);

            if(filesCount > 0) {

                for (int x = 0; x < filesCount; x++) {

                    String fileName = in.readLine();
                    String fileSize = in.readLine();

                    Log.d(LOG_TAG, "Соединяемся для приема файла:" + fileName + ", размер: " + fileSize);
                    Socket serverFile = new Socket();
                    serverFile.connect(new InetSocketAddress(serverAddress, PORT_FILE), CONNECTION_TIMEOUT);

                    byte[] buffer = new byte[8 * 1024];

                    FileOutputStream fos = new FileOutputStream(COBA_PATH + File.separator + fileName);
                    BufferedOutputStream bos = new BufferedOutputStream(fos);
                    DataInputStream dis = new DataInputStream(serverFile.getInputStream());

                    int count, total = 0;

                    while ((count = dis.read(buffer, 0, buffer.length)) != -1) {
                        total += count;
                        bos.write(buffer, 0, count);
                        bos.flush();

                        if (total == Long.parseLong(fileSize)) {
                            break;
                        }
                    }

                    fos.close();
                    bos.close();
                    dis.close();

                    serverFile.close();
                    Log.d(LOG_TAG, "Файл " + fileName + " принят, отключились ...");

                }

            }

            server.close();
            in.close();
            out.close();

            Log.d(LOG_TAG, "Отключились от сервера ...");

            setLastUpdateDate(Calendar.getInstance().getTimeInMillis());

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

    }





Сервер:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
    private void server() {

        try {
            ServerSocket s = new ServerSocket(PORT);
            System.out.println("Сервер запущен");

            while (true) {

                TimeUnit.MILLISECONDS.sleep(100);

                Socket client = s.accept();
                System.out.println("Клиент подключился");

                while (true) {

                    BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);
                    ArrayList<String> listNewFiles = new ArrayList<>();

                    String query = in.readLine();

                    String lastUpdateDate[] = query.split(":");
                    System.out.println("Получен запрос на скачивание");

                    for (File file : new File(COBA_PATH_NAME).listFiles()) {

                        long lastEditFile = file.lastModified();

                        if ((Long.parseLong(lastUpdateDate[1]) - lastEditFile) < 0) {

                            listNewFiles.add(file.getName());

                        }

                    }

                    out.println(listNewFiles.size());
                    out.flush();

                    for(String newFile : listNewFiles) {

                        out.println(newFile);
                        out.flush();

                        out.println(new File(COBA_PATH_NAME + File.separator + newFile).length());
                        out.flush();

                        System.out.println("Отправляем " + newFile);

                        ServerSocket s1 = new ServerSocket(PORT_FILES);
                        Socket client1 = s1.accept();

                        System.out.println("Клиент для скачивания подключился");

                        FileInputStream fis = new FileInputStream(new File(COBA_PATH_NAME + File.separator + newFile));
                        BufferedInputStream bis = new BufferedInputStream(fis);
                        DataOutputStream dos = new DataOutputStream(client1.getOutputStream());

                        byte[] buffer = new byte[8 * 1024];
                        int count, total = 0;

                        while ((count = bis.read(buffer, 0, buffer.length)) != -1) {
                            total += count;
                            dos.write(buffer, 0, count);
                            dos.flush();
                            System.out.println(total);
                        }

                        fis.close();
                        bis.close();
                        dos.close();

                        s1.close();
                        client1.close();

                        System.out.println("Клиент для скачивания отключился");

                    }

                    out.println("close");
                    out.flush();

                    in.close();
                    out.close();
                    
                    client.close();

                    System.out.println("Клиент отключился");
                    break;

                }

            }

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }

    }


...
Рейтинг: 0 / 0
Проблема при передаче файла между клиентом и сервером.
    #38828496
maxkar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
korshun,

Как-то оно все равно тяжело. По сокету на файл... Вот скажите, зачем вы создаете DataOutputStream для записи содержимого файла, если вы из него ни одного метода не используете (все методы есть в InputStream)?

Показываю псевдокод.

Сервер

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
  final DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(clientSocket));
  dos.writeInt(files.count);
  for (File file : files) {
    final long length = file.length();
    dos.writeUtf(file.getName());
    dos.writeLong(length);
    try(FileInputStream fis = new FileInputStream(file),
         BufferedInputStream bis = new BufferedInputStream(fis)) {
      copyExactNumber(bis, dos, length);
      if (bis.read() >= 0) {
         throw new NoEofException("За время копирования файл вырос");
      }
    }
  }




Клиент


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  final DataInputStream dis = new DataInputStream(new BufferedInputStream(socket));
  int remainingFiles = dos.readInt();
  while (remainingFiles --> 0) {
    final String name = dos.readUTF();
    final long length = dos.readLong();
    try (FileOutputStream fos = new FileOutputStream(name),
        BufferedOutputStream bos = new BufferedInputStream(fos)) {
      copyExactNumber(fis, dos, length);
    }
  }





Утилита

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
/** 
 * Copies exactly <code>len<code> bytes from input stream into the output stream.
 * @throws EOFException if input stream holds less than <code>len</code> bytes.
 * @throws IOException if read or write error occurs. State of streams is undefined after this exception.
 */
public static copyExactNumber(InputStream is, OutputStream os, long len) throws IOException {
  final byte[] buf = new byte[8 * 1024]
  while (len > 0) {
    final int rd = is.read(buf, 0, (int) Math.min(len, buf.length));
    if (rd < 0) {
      throw new EOFException("Missing remaining " + len + " bytes of input");
    }
    os.write(buf, 0, rd);
  }
}


...
Рейтинг: 0 / 0
Проблема при передаче файла между клиентом и сервером.
    #38829121
korshun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Понял, спасибо.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблема при передаче файла между клиентом и сервером.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]