volcom
volcom

Reputation: 5

Java Send String(filename) and file over same socket

I would SEND " filename" and "file " through socket , I was able to easily send the file but when I try to send strings eg PrintWriter pw.println ( ) or DataOutputStream or " out.writeUTF ( ) " the file is sent corrupt, I read a lot of questions on StackOverflow but have not found the answer , I'm looking for some example to send strings and files , can you help ?

server

package serverprova;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;



public class ServerProva {

final static int porta=8888;//porta server dove si collegano i client

public static void main(String[] args) throws IOException {
    // TODO code application logic here
    ServerSocket serverSocket=null;

    boolean ascoltando=true;

    serverSocket = new ServerSocket(porta);//avvia il server con il  numero di porta
    Socket s;
    BufferedReader br1=null;
     // ******  interfaccia f=new interfaccia);

      boolean r=true;
      BufferedInputStream bis=null;
       Scanner sc;
    FileOutputStream fout;

    while(ascoltando)
        {

        s=serverSocket.accept();// this socket 

    String filename="";
    String nome_cartella="";
    InputStream in = null;
OutputStream out = null;

   DataInputStream inString;


        inString = new DataInputStream(new BufferedInputStream(s.getInputStream()));
       //  filename = inString.readUTF();
       //  nome_cartella = inString.readUTF();



    in = s.getInputStream();



    //out = new FileOutputStream(nome_cartella+"/"+filename);
out = new FileOutputStream("ciao"+"/"+"asd.jpg");

byte[] b = new byte[20*1024];

int i ;


        while((i = in.read(b)) >0){
            out.write(b, 0, i);
        }
        out.close();
in.close();
//inString.close();
s.close();

        }


 }

}

client

    package clientprova;


import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;


public class ClientProva {
final static int porta=8888;

public static void main(String[] args) throws FileNotFoundException, IOException {
    File file;
    file = new File("kirlian12.jpg");
   InetAddress host = InetAddress.getLocalHost();
Socket sock = new Socket(host.getHostName(), 8888);
   DataOutputStream outString = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));

     //   outString.writeUTF(file.getName());
      //  outString.writeUTF("rivelatore2");
     //   outString.flush();

     byte[] b = new byte[20*1024]; 



                InputStream in = new FileInputStream(file);
        OutputStream out = sock.getOutputStream();

        int i ;

        while ((i = in.read(b)) >0    ) {
            out.write( b , 0 , i);
        }


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

sock.close();



   }


 }

when I try to uncomment the commented lines , my files get corrupted

Upvotes: 0

Views: 2073

Answers (1)

gudok
gudok

Reputation: 4179

When you wrap InputStream with BufferedInputStream, the latter "takes ownership" of InputStream. This means that when you call readUtf(), BufferedInputStream may read more bytes from InputStream than it is necessary for reading UTF string. So, when you next access InputStream directly, some part of transferred file is missing (because it was previously read into BufferedInputStream's buffer and currently resides there).

inString = new DataInputStream(new BufferedInputStream(s.getInputStream()));
filename = inString.readUTF();
nome_cartella = inString.readUTF();
...
in = s.getInputStream();
while((i = in.read(b)) >0){

You must choose from two alternatives: either to always use raw InputStream OR to always use BufferedInputStream. The same reasoning works also for OutputStream (but you managed to avoid problem by calling flush()).

Upvotes: 2

Related Questions