0

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

6
  • Please provide a minimal complete working example. Commented Apr 27, 2016 at 16:37
  • @SureshKoya ok work with commented line, i need to send 1 only string , sorry for the newbie question Commented Apr 27, 2016 at 17:09
  • If you only allow a certain number of bytes for the filename, then allow the remaining bytes for the file itself, you can easily parse the bytes upon receipt. Commented Apr 27, 2016 at 17:17
  • @ManoDestra you say that I send filename + file as a single package ? i need a small example Commented Apr 27, 2016 at 17:37
  • Yes, as a single packet. Allocate 256 bytes for the filename and ensure that you only write the filename to that section of the byte array. Then the remainder of your byte array will be the bytes of the file itself. Or you could have a header section of say 8 or 16 bytes which tells you the length of bytes for the filename and the length of bytes of the file. And then you can easily parse that upon receipt after reading the header bytes. Commented Apr 27, 2016 at 17:46

1 Answer 1

2

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()).

Sign up to request clarification or add additional context in comments.

3 Comments

ok , but I do not understand how to fix it , and I can not find any example to understand, if I should choose to use alone InputStream what should I do ?
Simply replace while ((i = in.read(b)) >0) { with while ((i = inString.read(b)) >0 ) {.
Thanks a lot, ,I'm new to Java , the study of Stream , for now, is the most difficult part to be studied .I have to study better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.