Входной поток объекта получает только один файл по сети? - PullRequest
0 голосов
/ 02 декабря 2010

Я создал базовый клиентский сервер, который будет отправлять файлы изображений в указанный каталог по сети. Код работал на прошлой неделе, но я вернулся к нему сегодня, и мне кажется, что я получаю только один файл на стороне сервера, хотя клиент печатает, что он отправил все файлы изображений в каталоге. Это может быть что-то в клиентском коде, но я думаю, что это что-то на стороне сервера. Любая помощь очень ценится, и если у вас есть более эффективное решение, я буду рад изменить мой код по мере необходимости. Мой код ниже:

ImageServer

        package com.encima.network.server;

        import java.io.*;
        import java.net.*;

        public class ImageServer{

     ServerSocket ss;
     Socket s;
     ObjectOutputStream oos;
     int port = 4440;

     public ImageServer() throws IOException {
      try {
       ss  = new ServerSocket(port);
       System.out.println("Server started on Port: " + port);
      } catch(IOException e) {
       System.out.println("Serevr: Port-" + port  + " not available, exiting.");
       System.exit(0);
      }

      System.out.println("Server: Waiting for Client Connection...");

      while(true) {
       try {
        s = ss.accept();
        new ImageHandler(s);
       } catch (IOException e) {
        e.printStackTrace();
       }
      }
     }

     public static void main(String[] args) throws IOException {
      ImageServer is = new ImageServer();
     }

        }

ImageHandler

    package com.encima.network.server;

    import java.awt.image.BufferedImage;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.net.Socket;

    import javax.imageio.ImageIO;

    public class ImageHandler implements Runnable {

     Socket s;
     int count = 0;

     public ImageHandler(Socket socket) {
      s = socket;
      Thread t = new Thread(this);
      t.start();
     }

     @Override
     public void run() {

      try {
       ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
       FileOutputStream fos = new FileOutputStream("image" + System.nanoTime() + ".jpg");
       count++;
       //BufferedImage in = ImageIO.read(ois);
       //ImageIO.write(in, "jpg", fos);

       int ch = 0;
        while(true) {
         ch = ois.read();
          if(ch == -1) {
           break;
          }
         fos.write(ch);
        }   
       fos.flush();
      } catch (Exception e) {
       e.printStackTrace();
      }
     }
    }



Finally, the ImageClient

    package com.encima.network.client;

    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.net.Socket;

    import javax.imageio.ImageIO;

    import com.encima.network.ImageFilter;


    public class ImageClient {

     Socket s;
     String ip = "localhost";
     int port = 4440;
     ObjectOutputStream oos;

     public ImageClient(File[] files) throws IOException, ClassNotFoundException, InterruptedException {

      try {
       s = new Socket(ip, port);
       System.out.println("Client connected to Server via " + ip + " on port 80");
      } catch (Exception e) {
       System.out.println("Client: Cannot find Host: " + ip + ". Exiting.");
       System.exit(0);
      }

      oos = new ObjectOutputStream(s.getOutputStream());

      for(File f: files) {
       sendFile(f);
      }
      oos.close();
       //System.out.println("Written Image " + i + " of " + files.length);
     }

     public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
      File dir = new File("/Users/christophergwilliams/Dropbox/PhD/Projects/PhD/Year 1/GSN/images");
      File[] files = dir.listFiles(new ImageFilter());
      ImageClient ic = new ImageClient(files);
     }

     public void sendFile(File file) throws IOException {
      FileInputStream fis = new FileInputStream(file);
      //BufferedImage b = ImageIO.read(file);
      //ImageIO.write(b, "jpg", oos);
      int ch = 0;
       while(true) {
        ch = fis.read();
        if(ch == -1) {
         break;
        }
        oos.write(ch);
       }
      oos.flush();
      System.out.println("Image Sent");

     }


}

Я знаю, что много кода для чтения, но я ценю любую помощь, которую я могу получить в этом!

Я могу ошибаться, но для эффективности и сетевого трафика было бы полезно отправлять изображения в виде почтового индекса с клиента на сервер?

1 Ответ

3 голосов
/ 02 декабря 2010

Почему вы вообще используете ObjectInputStream? Вы не читаете и не пишете никаких сериализованных объектов - просто необработанные двоичные данные. Используйте все, что указано в InputStream, и читайте из него.

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

  • Используйте разделитель между файлами (очень некрасиво - вам может понадобиться экранировать любые данные, которые выглядели как разделитель при продвижении)
  • Префикс каждого файла с его длиной
  • Отправить каждый файл по отдельному соединению

(Вы также читаете и записываете по одному байту за раз. Используйте перегрузки чтения / записи, которые принимают байтовые массивы.)

...