File Transfer malformed input - java

Currently trying to have the server send a file to the client.
I'm able to see the file being created in the client directory, but it won't send all the bytes. Sometimes its 90% of the bytes, and sometimes its not even 10 bytes.
I keep getting a message from the terminal window saying: "malformed input around byte...."
Here's the Server code for this section:
String cMessage;
DataInputStream input= new DataInputStream( remote_socket.getInputStream() );
File filename = new File(cMessage);
try {
input = new DataInputStream(new FileInputStream(filename));
DataOutputStream out = new DataOutputStream(remote_socket.getOutputStream());
byte[] buffer = new byte[(int) filename.length()];
int count;
while((count = input.read(buffer)) >0){
out.write(buffer, 0, count);
}
System.out.println("Sending " + cMessage + " that is " + filename.length());
out.flush();
} catch (IOException e) {
System.out.println(e + "......");
e.printStackTrace();
}
Output for the Server when running looks like:
Sending test.png that is 723915
Here's the Client for this section:
try {
BufferedReader reader= new BufferedReader(
new InputStreamReader(System.in) );
String message;
BufferedReader fileMessageReader= new BufferedReader(
new InputStreamReader(System.in) );
String fileMessage;
DataOutputStream output= new DataOutputStream(this.client_socket.getOutputStream() );
DataInputStream input = new DataInputStream(this.client_socket.getInputStream());
while(true) {
while( (message = reader.readLine()) != null ) {
System.out.println("1. For a text message. 2. For a file");
if (message.equals("2")) {
System.out.println("Name of file?");
fileMessage = fileMessageReader.readLine();
output.writeUTF(fileMessage);
try {
File filename = new File(fileMessage);
DataOutputStream fileOutput = new DataOutputStream(new FileOutputStream(filename));
byte[] buffer = new byte[1024];
int count;
while((count = input.read(buffer)) >0){
fileOutput.write(buffer, 0, count);
}
fileOutput.flush();
fileOutput.close();
} catch (IOException e) {
System.out.println(e + "...");
}
} else {
output.writeUTF( message );
}
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}

while ((c = input.read()) != -1) {
output.write(c);
}
This piece is killing it. If you read javadoc carefully, rather than just checking method signature, you will see that read() reads a single byte from the input (it returns int only to be able to signal end of stream with -1). So you read byte as int, no big deal, but then you blindly write aforementioned int (4 bytes) into the output stream.
You should use read(byte[] b) instead and then write the whole array (or only part of it that was read in the last round).

Related

Read complete file without looping in android

i need a solution for reading a text file which was stored in internal storage.
i don't want to read it line by line. without use looping how to read a complete text file and store it into a string.
BufferedReader br;
String line;
String data = "";
// String text="";
try {
br = new BufferedReader(new FileReader(new File(Environment.getExternalStorageDirectory(), "queue_mgr.txt")));
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
}
You can use a large byte buffer and gain some efficiency:
try
{
InputStream in = new FileInputStream (from);
OutputStream out = new FileOutputStream (to);
// Transfer bytes from in to out
byte[] buf = new byte[1024 * 10]; // 5MB would be about 500 iterations
int len;
while ((len = in.read (buf)) > 0)
out.write (buf, 0, len);
in.close ();
out.close ();
}
}
catch (FileNotFoundException e)
{
...
}
catch (IOException e)
{
...
}

When image is sent to server I get this error "java.io.UTFDataFormatException: malformed input around byte 1869" [duplicate]

I have two projects; one for my server and one for my client, I am able to send images to the server with ease. But I am wondering how would you be able to download that image you just sent to the server back to the client when I press the download button I have created on my client GUI? My code is written in java.
Many Thanks
This is my serverhandler
String fileName;
fileName = "RecievedImageoutreach1.jpg";
DataOutputStream dout = new DataOutputStream(sock.getOutputStream());
//Coding for image transfer
int flag=0,i;
String extn="";
for(i=0; i<fileName.length(); i++)
{
if(fileName.charAt(i)=='.' || flag==1)
{
flag=1;
extn += fileName.charAt(i);
}
}
if(extn.equals(".jpg") || extn.equals(".gif"))
{
try{
File file = new File(fileName);
FileInputStream fin = new FileInputStream(file);
dout.writeUTF(fileName);
byte[] readData = new byte[1024];
while((i = fin.read(readData)) != -1)
{
dout.write(readData, 0, i);
}
//ta.appendText("\nImage Has Been Sent");
dout.flush();
fin.close();
}catch(IOException ex)
{System.out.println("Image ::"+ex);}
}
}
And this is my client
public void download() throws IOException {
// Get input from the server
DataInputStream dis = new DataInputStream (sock.getInputStream());
String str,extn = "";
str = dis.readUTF();
int flag=0,i;
for(i=0;i<str.length();i++)
{
if(str.charAt(i)=='.' || flag==1)
{
flag=1;
extn+=str.charAt(i);
}
}
//**********************reading image*********************************//
if(extn.equals(".jpg") || extn.equals(".gif"))
{
File file = new File("Downloaded"+str);
FileOutputStream fout = new FileOutputStream(file);
//receive and save image from client
byte[] readData = new byte[1024];
while((i = dis.read(readData)) != -1)
{
fout.write(readData, 0, i);
if(flag==1)
{
ta.append("Image Has Been Downloaded");
flag=0;
}
}
fout.flush();
fout.close();
}
}
But when run nothing occurs? i have linked the client method to run when a button is clicked.
I would do something like this:
//Server Handler
File file = new File(fileName);
FileInputStream fin = new FileInputStream(file);
// dout.writeUTF(fileName);
byte[] readData = new byte[1024];
fin.read(readData);
fin.close();
dout.write(readData, 0, readData.length);
dout.flush();
/* while((i = fin.read(readData)) != -1)
{
dout.write(readData, 0, i);
}*/
//ta.appendText("\nImage Has Been Sent");
dout.flush();
fin.close();
}catch(IOException ex)
{System.out.println("Image ::"+ex);}
}
//Receiving image
if(extn.equals(".jpg") || extn.equals(".gif"))
{
//give path to new file
File file = new File(".//Downloaded"+str);
FileOutputStream fout = new FileOutputStream(file);
//receive and save image from client
byte[] readData = new byte[1024];
int offset =0;
while((i = dis.read(readData,0,readData.length-offset)) != -1){
offset += i;
}
fout.write(readData, 0, readData.length);
if(flag==1)
{
ta.append("Image Has Been Downloaded");
flag=0;
}
fout.flush();
fout.close();
}
}
Assuming that you would have to provide file name and then press download button. So on server side convert the image into byte stream and write over the connection socket. On client side recieve bytes into buffer and then create FileOutputStream providing the directory for output. Write the recieved bytes onto the file using the outputstream created.

how to transfer a file in network (socket programming(TCP) ) in android [duplicate]

This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 7 years ago.
i'm trying to send some files from a server to some clients in android.
i receive the file through a bufferedInputStream by read(byte[] array,int startIndex,int arraySize) method that returns the number of bytes it can read and -1 if there is no input to read.
i receive the file in a loop and i must go out of the loop when my file finishes, but the read method is not returns -1 and just waiting for more input to read :/
so my code is blocking....
i tried to send the file size from the server and when receiving it,and subtract number reads byte from it every time i read a buffer, so when this number hits 0 means i received all file and should break the loop, BUT in some files it doesn't hit 0 as if some part of my file is not sent :| but when i do the same thing in the server side (subtract the sent part from the early file size) it always hit 0 ....
SO my problem is how to know i read all file to break the reading loop :(
similar question
my question is differ from this link because i done the suggested answer but the remaining file size is NOT reach 0 in some files and i dont know why
here is my code for send the file in sever side:
public void sendFile(File file){
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(file));
bos = new BufferedOutputStream(outputStream);
byte[] temp = new byte[2 * 1024];
int length ;
int fileSize=(int)file.length();
Log.d("file size",Integer.toString(fileSize));
//int sendSize =0;
while (true){
length = bis.read(temp,0,temp.length);
if(length == -1) break;
bos.write(temp,0,length);
fileSize-=length;
assert (fileSize >=0 );
//if(fileSize==0)break;
}
// outputStream.write(-1);
bos.flush();
Log.d("File ", "Send finisheeed!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}finally {
try {
bis.close();
//bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and here is the part of client code that receives the file :
Log.d("File name is", fileName);
// File outFile = new File("/storage/sdcard0/m2app" + fileName);
// outFile.createNewFile();
bos = new BufferedOutputStream(new FileOutputStream("/storage/sdcard0/m2app" + fileName));
byte[] temp = new byte[2 * 1024];
int length = 0;
while (true)
{
length = bis.read(temp,0,temp.length);
fileLength -= length;
// Log.d("read",Integer.toString(fileLength) );
if(length == -1 || fileLength == 0 ) {
// if(temp[length-1] == -1){
// bos.write(temp,0,length-1);
// bos.flush();
// Log.d("file","recived!!!!!!!!!!");
break;
}
if(fileLength < 4000 && bis.available() == 0)
break;
bos.write(temp,0,length);
bos.flush();
/*if(fileLength == 0){
Log.d("file","0 shod");
break;
}*/
}
while (fileLength > 0 )
fileLength-=bis.skip(fileLength);
// inputStream.reset();
bos.close();
Log.d("File " , "Receiving finisheeeeeeeeeddddd!!!");
isFile = false;
You need to close the output stream in the file sender for the input stream in the file receiver to get the EOF.
Using try-with-resources you can dramatically simplify the code:
public void sendFile(File file) {
try(BufferedOutputStream bos = new BufferedOutputStream(outputStream);
FileInputStream fis = new FileInputStream(file));
BufferedInputStream bis = new BufferedInputStream(fis)) {
byte[] temp = new byte[64 * 1024];
int length ;
int fileSize=(int)file.length();
Log.d("file size",Integer.toString(fileSize));
while ((bis.read(temp,0,temp.length) != -1){
bos.write(temp,0,length);
}
Log.d("File ", "Send finished!");
} catch (IOException e) {
e.printStackTrace();
}
}

Packet loss in socket programming java

I am trying to send a file from client to server. Below is the code i have tried. But at times, there is a packet loss during the transfer. I am not sure where i am wrong.
SERVER SIDE CODE:
public static void ReadAndWrite(byte[] aByte, Socket clientSocket,
InputStream inputStream, String fileOutput)
throws FileNotFoundException, IOException {
int bytesRead;
FileOutputStream fileOutputStream = null;
BufferedOutputStream bufferedOutputStream = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try
{
fileOutputStream = new FileOutputStream( fileOutput );
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
bytesRead = inputStream.read(aByte, 0, aByte.length);
System.out.println("The length is "+bytesRead);
int count = 0;
do {
count++;
byteArrayOutputStream.write(aByte);
bytesRead = inputStream.read(aByte);
} while (bytesRead != -1);
System.out.println("The count is "+count);
System.out.println("The length is "+byteArrayOutputStream.size());
bufferedOutputStream.write(byteArrayOutputStream.toByteArray());
bufferedOutputStream.flush();
bufferedOutputStream.close();
clientSocket.close();
}
catch(Exception ex)
{
Logger.writeLog(ex,Listen.class.getName(), LogType.EXCEPTION);
throw ex;
}
CLIENT SIDE CODE:
public void readByteArrayAndWriteToClientSocket(
Socket connectionSocket, BufferedOutputStream outToClient, String fileToSend ) throws Exception
{
try{
if (outToClient != null)
{
File myFile = new File(fileToSend);
System.out.println(myFile.length());
byte[] byteArray = new byte[(int) myFile.length()];
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(myFile);
} catch (IOException ex) {
Logger.writeLog(ex, FileUtility.class.getName(), LogType.EXCEPTION);
throw ex;
}
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
try {
bufferedInputStream.read(byteArray, 0, byteArray.length);
outToClient.write(byteArray, 0, byteArray.length);
outToClient.flush();
outToClient.close();
connectionSocket.close();
return;
} catch (IOException ex) {
Logger.writeLog(ex, FileUtility.class.getName(), LogType.EXCEPTION);
throw ex;
}
}
}catch (Exception e) {
Logger.writeLog(e, getClass().getName(), LogType.EXCEPTION);
throw e;
}
}
There is no 'packet loss', just bugs in your code.
The canonical way to copy a stream in Java is as follows:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
If you know the number of bytes in advance and the sender must keep the connection open after the transfer, it becomes:
while (total < expected && (count = in.read(buffer, 0, expected-total > buffer.length ? buffer.length : (int)(expected-total))) > 0)
{
out.write(buffer, 0, count);
total += count;
}
Forget all the ByteArrayInput/OutputStreams and the extra copies. Just read from the file and send to the socket, or read from the socket and write to the file.
The sockets read method will return when its has obtained all the bytes you asked for, OR, when it stops receiving data from the network.
As transmission is often interrupted in any real network you need to keep issuing read calls until you have the number of bytes you want.
You need code something like this:
char [] buffer = new char[1024];
int expect = 1000;
int sofar = 0;
int chars_read;
try
{
while((chars_read = from_server.read(buffer[sofar])) != -1)
{
sofar = sofar + chars_read;
if (sofar >= expected) break;
}
}
catch(IOException e)
{
to_user.println(e);
}

Socket closed issues

I have a server and client connection using sockets to transfer files, but if I want to be able to send strings to the server from the client upon user JButton actions, it throws socket closed errors (Because I used dos.close() in the Sender() constructor). The problem is, if I don't use dos.close(), the client program won't run/init the UI frame. What am I doing wrong? I need to be able to send files when the program first runs then send data later.
Sender:
public Sender(Socket socket) {
List<File> files = new ArrayList<File>();
files.add(new File(Directory.getDataPath("default.docx")));
files.add(new File(Directory.getDataPath("database.db")));
try {
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(files.size());
for (File file : files) {
dos.writeLong(file.length());
dos.writeUTF(file.getName());
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
int theByte = 0;
while ((theByte = bis.read()) != -1) {
bos.write(theByte);
}
bis.close();
}
dos.close(); // If this is disabled, the program won't work.
} catch (Exception e) {
e.printStackTrace();
}
}
Downloader:
public static byte[] document;
public Downloader(Socket socket) {
try {
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
DataInputStream dis = new DataInputStream(bis);
int filesCount = dis.readInt();
for (int i = 0; i < filesCount; i++) {
long size = dis.readLong();
String fileName = dis.readUTF();
if (fileName.equals("database.db")) {
List<String> data = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(bis));
String line;
while ((line = reader.readLine()) != null) {
if (line.trim().length() > 0) {
data.add(line);
}
}
reader.close();
parse(data);
} else if (fileName.equals("default.docx")) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int x = 0; x < size; x++) {
bos.write(bis.read());
}
bos.close();
document = bos.toByteArray();
}
}
//dis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Your first receive loop in the client terminates at EOS, which only happens when you close the socket in the sender, which you don't want to do. You're sending the length ahead of the file in each case so the receiving code should look like this in both cases:
long total = 0;
while ((total < size && (count = in.read(buffer, 0, size-total > buffer.length ? buffer.length : (int)(size-total))) > 0)
{
total += count;
out.write(buffer, 0, count);
}
out.close();
That loop reads exactly size bytes from the socket input stream and writes it to the OutputStream out, whatever out happens to be: in the first case, a FileOutputStream, in the second, a ByteArrayOutputStream.

Categories