How to make sure that the file passed using java.net is as it was before transmission

StackOverflow https://stackoverflow.com/questions/17703323

  •  03-06-2022
  •  | 
  •  

Pergunta

I'm studying java.net and trying to transmit som file. here is the sender code

public static final FilesGetter filesGetter = new FilesGetter();
    public static Socket s;
    public static File[] files;

    public static void main(String args[]) throws Exception{
        s = new Socket("localhost", 3128);

        while (true){
            try{
                files = filesGetter.getFilesList("/etc/dlp/templates/");
                Socket s = new Socket("localhost", 3128);
                args[0] = args[0]+"\n"+s.getInetAddress().getHostAddress()
                        +":"+s.getLocalPort();
                if (files != null){
                    for (int i = 0; i < files.length; i++){
                        InputStream is = new FileInputStream(files[i]);
                        byte[] message = IOUtils.toByteArray(is);
                        s.getOutputStream().write(message);

                        byte buf[] = new byte[64*1024];
                        int r = s.getInputStream().read(buf);
                        String data = new String(buf, 0, r);

                        System.out.println(data);
                    }
                }
            } catch(Exception e){
                System.out.println("init error: "+e);
            }
        }    
    }

And here is the receiver code:

public class Consumer extends Thread{

    public static Socket s;
    public String customerId;
    int num;
    public static final Filter filter = new Filter();
    public MimeParser mimeParser = new MimeParser(true);

    public Consumer(int num, final Socket s, final String customerId){
        this.num = num;
        this.s = s;
        this.customerId = customerId;

        setDaemon(true);
        setPriority(NORM_PRIORITY);
        start();
    }

    public static void receive(final String customerId){
        try {
            int i = 0;

            ServerSocket server = new ServerSocket(3128, 0, InetAddress.getByName("localhost"));

            System.out.println("server started");
            while (true){
                new Consumer(i, server.accept(), customerId);
                i++;
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    public void run(){
        try {
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();

            byte buf[] = new byte[64*1024];
            int r = is.read(buf);

            if (r < 0)
                    return;
            ByteArrayInputStream bais = new ByteArrayInputStream(buf, 0, r);
            MessageInfo mi = mimeParser.parseMessages(bais);
            filter.getMessageAcceptability(mi.getPlainText(), customerId);
            s.close();
        } catch (Exception e){
            System.out.println("init error: " + e);
        }
    }
}

I'm not sure of data integrity because processing of data on the server-side is not fully successful and don't know if I need to look for mistakes in the processing code(which worked well when I've been Using rabbitmq) or in client-server code. I also don't know what buffer size must be chosen.

Foi útil?

Solução

At the sender side you can send as much as you want, 64*1024 it's OK, the send method will loop until all the data has been delivery. But at the receiver it could be that read returns before the whole file has been read, you must loop reading until the other side closes the socket.

In these cases it's better to send, in advance, an integer indicating how much data you are going to send, the receiver will loops until that much bytes are read.

For example:

int ret=0;
int offset=0;
int BUFF_LEN=64*1024;
byte[] buffer = new byte[BUFF_LEN];
while ((ret = is.read(buffer, offset, BUFF_LEN - offset)) > 0)
{
    offset+=ret;
    // just in case the file is bigger that the buffer size
   if (offset >= BUFF_LEN) break;
}

Outras dicas

You need to compute a checksum like SHA-1 on both the sender and the receiver's side. When they match, you can assume that there was no transmission error. Your question is really more of a protocol question.

A much simpler and more practical solution than to implement your own integrity checks would be to use the SSL protocol. That will provide you with integrity checked transmissions.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top