Как читать несколько типов данных из сокета на Java - PullRequest
0 голосов
/ 08 ноября 2019

Я пишу приложение для передачи файлов. Между клиентом и сервером я посылаю 3 типа данных:

1) Некоторые «командные слова», такие как READY_FOR_UPLOAD.

2) Некоторые сериализуемые данные

3) Большие файлы в байтахмассив.

Я получаю клиентские соединения на сокете сервера и создаю новый поток для каждого клиента.

    try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
    InputStream inputStream = clientSocket.getInputStream();
    ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {}

Я создаю эти потоки, используя try с ресурсами, и проблем не возникает.

Я использую:

1) «in» для чтения сообщений от клиента:

    String line;
    while ((line = in.readLine()) != null) {
      System.out.println(line);
    }

2) «out» для отправки сообщений.

3) «inputStream»«для получения файлов:

    try (FileOutputStream fileOutputStream = new  
              FileOutputStream("D:\\testDownload.zip");
         BufferedOutputStream bufferedOutputStream = new 
               BufferedOutputStream(fileOutputStream)
            ) {
                byte[] buffer = new byte[1024 * 100];
                int read;
                while ((read = inputStream.read(buffer)) != -1) {
                   bufferedOutputStream.write(buffer, 0, read);
                }

            }

4)« objectInputStream »для сериализуемых данных:

    Object object;
    if ((object = objectInputStream.readObject()) != null) {
        if (object instanceof File) {
              File file = (File) object;
              System.out.println(file.getAbsolutePath());
              System.out.println(file.length());
          }
     }

Пока я использую их отдельно - проблем нет. Но прежде всего мне нужно прочитать «командное слово», т.е. при запуске метода моего шага.

    public void run() {
    try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
    InputStream inputStream = clientSocket.getInputStream();
    ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
      String line;
     if ((line = in.readLine()) != null) {
      System.out.println(line);

     there i should try to read other types of data
    }
    }

И если это не «командное слово», я могу попробовать прочитать сериализуемые данные или данные файла. Но это проблема! Я могу попытаться прочитать строку, но она может быть частью сериализуемых данных файловых данных, и так как inputream считал байтовый метод «один за другим», я не могу попробовать прочитать его как сериализуемые или файловые данные, потому что ввод больше не является целымЯ прочитал некоторые данные в «readLine ()». Я должен знать, какой тип данных я получаю, прежде чем пытаться их прочитать. Как это можно сделать?

1 Ответ

0 голосов
/ 09 ноября 2019

Вам необходимо создать протокол - правила обмена информацией между клиентом и сервером. Когда вы пишете данные, вы указываете, какой тип данных вы отправляете, и его размер. И не используйте ObjectInputStream и ObjectOutputStream для Socket - конвертируйте данные в массив байтов, чтобы вы знали, какой размер при записи, а затем конвертировали их обратно. Отправьте данные в байтах.

...