Welcome, Guest: Register On Nairaland / LOGIN! / Trending / Recent / New
Stats: 3,152,457 members, 7,816,069 topics. Date: Friday, 03 May 2024 at 02:12 AM

Problem With Bufferedinputstream Read Blocking Issue In Java - Programming - Nairaland

Nairaland Forum / Science/Technology / Programming / Problem With Bufferedinputstream Read Blocking Issue In Java (4526 Views)

. / I Want To Develop A Software In Java To Calculate CGPA / How Do Io Create Ribbon Ui In Java (2) (3) (4)

(1) (Reply) (Go Down)

Problem With Bufferedinputstream Read Blocking Issue In Java by nollyj: 10:49pm On Oct 15, 2013
I wrote a client server application that list all the files in the server and can download any file in the server with a command. Everything seems to be working well but I am having a problem with downloading files to the client due to read blocking.

Problem case

When the client request to download a file in the server, the server send the content of the file in bytes.
The client will start to read the received byte into a buffer and the size of the buffer is 8192 which I got from int bSize = clientSocket.getReceiveBufferSize();

Since the buffer size from the server is less than that of client, the client blocks after reading the bytes from the server since it is still waiting for more and the server has less.

Server Code
private static void DownloadFileFromServer(BufferedInputStream bis, String filePath){


try {
stream = new FileOutputStream(pathtoClientDirectory + filePath);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

try {
int bSize = clientSocket.getReceiveBufferSize();
int nRead;
byte[] data = new byte[bSize];

try {
while ((nRead = bis.read(data, 0, data.length)) != -1) {
stream.write(data, 0, nRead);

try {
clientSocket.setSoTimeout(100);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


Server Code


private static void sendFileToClient(String filename){

try{
File myFile = new File(pathtofileDirectory + filename);


byte[] mybytearray = new byte[(int) myFile.length()];

System.out.println("Length of file to read" + mybytearray.length);

FileInputStream ips = new FileInputStream(myFile);
BufferedInputStream biss = new BufferedInputStream(ips);
int nRead;


while ((nRead = biss.read(mybytearray, 0, mybytearray.length)) != -1) {

buffersp.write(mybytearray, 0, nRead);
buffersp.flush();
}
biss.close();
//buffersp.close();

}catch(IOException ex){
System.out.println(ex.getMessage());
}


I have used the socket setTimeout which works but it always throws Java socket exception. I have also tried using separate thread for each server connection but it did not know for me. I need suggestion or point on how best to solve this.

Thanks
Re: Problem With Bufferedinputstream Read Blocking Issue In Java by BetaQuick: 2:19am On Oct 16, 2013
You are trying to read greater than whats in the buffered input stream.

Why dont you try a bytearrayoutputstream. See below

// output bucket to read data
ByteArrayOutputStream os = new ByteArrayOutputStream();
// read the response data
InputStream in = new BufferedInputStream(conn.getInputStream());

int read = 0; byte[] data = new byte[1024];
while((read = in.read(data)) > 0) {
os.write(data, 0, read);
}

// Your data is now in the ByteArrayOutputStream for reading
Re: Problem With Bufferedinputstream Read Blocking Issue In Java by nollyj: 9:01am On Oct 16, 2013
BetaQuick: You are trying to read greater than whats in the buffered input stream.

Why dont you try a bytearrayoutputstream. See below

// output bucket to read data
ByteArrayOutputStream os = new ByteArrayOutputStream();
// read the response data
InputStream in = new BufferedInputStream(conn.getInputStream());

int read = 0; byte[] data = new byte[1024];
while((read = in.read(data)) > 0) {
os.write(data, 0, read);
}

// Your data is now in the ByteArrayOutputStream for reading

Thanks, but it still gives the same problem since the blocking occurs here in.read(data)
Re: Problem With Bufferedinputstream Read Blocking Issue In Java by BetaQuick: 10:34am On Oct 16, 2013
Ok, the reason why your read is blocking is because I suspect the socket is still open.

Keep in mind that you cannot always just read from the Socket's InputStream until it returns -1, as you can when reading a file. The reason is that -1 is only returned when the server closes the connection. But a server may not always close the connection. Perhaps you want to send multiple requests over the same connection. In that case it would be pretty stupid to close the connection.

Instead you must know how many bytes to read from the Socket's InputStream. This can be done by either the server telling how many bytes it is sending, or by looking for a special end-of-data character.
Re: Problem With Bufferedinputstream Read Blocking Issue In Java by nollyj: 11:16am On Oct 16, 2013
BetaQuick:
Instead you must know how many bytes to read from the Socket's InputStream. This can be done by either the server telling how many bytes it is sending, or by looking for a special end-of-data character.

Thanks once again. If you look at my first post, using this method call gets the amount of bytes the server is excepting from the client.

int bSize = clientSocket.getReceiveBufferSize(); This returns 8192 when you print out bSize;

Since the client is send less than 8192 bytes, the BufferedInputStream read action keep waiting (Blocking) for the client to complete this amount.

1. I observed that when I close the connection it automatically flushes out the stream but I am using the connection for multiple read so it will be open until I choose to close it.

2. That is why I mentioned that I used timeout socket method since I know that the client have finish reading the bytes from server irrespective of the fact that it still waits for more bytes that the client does not have.

I think I have to try JAVA NIO in Java 7 API since it has non-blocking read functionality.

Thanks for your help
Re: Problem With Bufferedinputstream Read Blocking Issue In Java by BetaQuick: 7:32pm On Oct 16, 2013
yea but in your code you are looking for the -1

while ((nRead = bis.read(data, 0, data.length)) != -1)

That wont happen since your socket remains open. You have to stop when you have the bytes expected
OR put a special character to stop reading.

Since your client is sending less than 8192, I would go for the special character to signify end of data.

Good Luck!
Re: Problem With Bufferedinputstream Read Blocking Issue In Java by ToyinDipo(m): 8:05pm On Oct 16, 2013
I don't know whether this that I'm posting might help. I wrote the sh1t 5 years ago while still in school, I don't even understand half of what it means again. But since you are still active in java programming you should be able to decode it. It designed it to transfer files between two PC's.

Server side (which must be run first)

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package transferdata;

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
//import javax.swing.filechooser.FileFilter;
//import javax.swing.filechooser.FileNameExtensionFilter;

/**
*
* @author
*/

public class TransferServer {
private ObjectOutputStream output;
private ObjectInputStream input;
private DataInputStream datain;
private ServerSocket server;
private Socket con;
public TransferServer(){
startServer();
processData();
}
public void startServer(){
try{
server=new ServerSocket(30000,1);
con=server.accept();
output=new ObjectOutputStream(con.getOutputStream());
output.flush();
input=new ObjectInputStream(con.getInputStream());
}
catch(IOException ex){
ex.printStackTrace();
System.exit(1);
}

}
public File getFile(){
JFileChooser fileChooser = new JFileChooser();

/*FileFilter filter1 = new FileNameExtensionFilter("JPEG Files","jpg","jpeg"wink;
FileFilter filter2 = new FileNameExtensionFilter("Multimedia Files","mp3","mp4"wink;
fileChooser.addChoosableFileFilter(filter1);
fileChooser.addChoosableFileFilter(filter2);
*/
int result = fileChooser.showOpenDialog(null);
if(result==JFileChooser.CANCEL_OPTION)
System.exit(1);
File file = fileChooser.getSelectedFile();
if((file==null)||(file.getName().equals(""wink)){
JOptionPane.showMessageDialog(null, "Invalid File Selection"wink;
System.exit(1);
}
return file;

}
public void processData(){
File file=getFile();
if(file.exists()){
String path = file.getPath();
String name = file.getName();
try{
datain= new DataInputStream(new FileInputStream(path));
output.writeObject("Needs data"wink;
output.flush();
String response = (String)input.readObject();
output.writeObject(name);
output.flush();
response = (String) input.readObject();
if(response.equals("Send data"wink)
sendData();
}
catch(ClassNotFoundException ex){
ex.printStackTrace();
JOptionPane.showMessageDialog(null,"Data Transfer Not Succesful", "Sender", JOptionPane.ERROR_MESSAGE);
close();
System.exit(1);
}

catch(EOFException ex){
JOptionPane.showMessageDialog(null,"Data Transfer Succesful", "Sender", JOptionPane.PLAIN_MESSAGE);
close();
//System.exit(0);
}

catch(IOException ex){
ex.printStackTrace();
JOptionPane.showMessageDialog(null,"Data Transfer Not Succesful", "Sender", JOptionPane.ERROR_MESSAGE);
close();
System.exit(1);

}
}
else {
close();
System.exit(1);
}


}
public void sendData()throws EOFException,IOException{
byte[] inByte=new byte[2048];
while(true){

int len=datain.read(inByte);
if(len>0){
output.write(inByte,0,len);
output.flush();
}
else
throw new EOFException();
//int len =(Integer) input.readObject();
//output.writeObject("Received"wink;
//output.flush();
//dataout.write(inByte);
}

}
public void close(){
try{
datain.close();
input.close();
output.close();
con.close();
}
catch(IOException ex){
ex.printStackTrace();
System.exit(1);
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
new TransferServer();
}

}


Client side

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package transferclient;

import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

/**
*
* @author
*/
public class TransferClient {
private Socket socket;
private DataOutputStream dataout;
private ObjectInputStream input;
private ObjectOutputStream output;
private String host;
/**
* @param args the command line arguments
*/
public TransferClient(String _host){
host=_host;
startClient();
waitAndRead();
}
public void startClient(){
try {
socket=new Socket(InetAddress.getByName(host),30000);
output=new ObjectOutputStream(socket.getOutputStream());
output.flush();
input = new ObjectInputStream(socket.getInputStream());

}
catch(IOException ex){
ex.printStackTrace();
close();
System.exit(1);
}
}
public void waitAndRead(){
String response;
try{
response=(String) input.readObject();
if(response.equals("Needs data"wink){
output.writeObject("Yes"wink;
output.flush();
response=(String)input.readObject();
try{
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result=fileChooser.showSaveDialog(null);
if(result==JFileChooser.CANCEL_OPTION)
throw new IllegalStateException("No Directory Selected"wink;
File sFile = fileChooser.getSelectedFile();
if(!sFile.exists())
throw new IllegalStateException("Invalid Directory"wink;
File file =new File(sFile,response);
dataout = new DataOutputStream(new FileOutputStream(file));
output.writeObject("Send data"wink;
}
catch(IllegalStateException ex){
ex.printStackTrace();
}
catch(NullPointerException nex){
nex.printStackTrace();
}
catch(FileNotFoundException ex){
ex.printStackTrace();

}
catch(SecurityException ex){
ex.printStackTrace();
}
finally{
output.writeObject("Not again"wink;
output.flush();
}
readData();

}
else close();

}catch(ClassNotFoundException ex){
ex.printStackTrace();
JOptionPane.showMessageDialog(null,"Data Transfer Aborted", "Receiver", JOptionPane.ERROR_MESSAGE);
close();
System.exit(1);

}
catch(EOFException ex){
close();
JOptionPane.showMessageDialog(null,"Data Transfer Succesful", "Receiver", JOptionPane.PLAIN_MESSAGE);

}
catch(IOException ex){
ex.printStackTrace();
JOptionPane.showMessageDialog(null,"Data Transfer Aborted", "Receiver", JOptionPane.ERROR_MESSAGE);
close();
System.exit(1);

}
}
public void readData()throws EOFException,IOException{
byte[] inByte=new byte[2048];
while(true){

int len=input.read(inByte);
if(len>0)
dataout.write(inByte,0,len);
else
throw new EOFException();
//int len =(Integer) input.readObject();
//output.writeObject("Received"wink;
//output.flush();
//dataout.write(inByte);
}


}
public void close(){
try{
dataout.close();
input.close();
output.close();
socket.close();
}
catch(IOException ex){
ex.printStackTrace();
System.exit(1);
}
}
public static void main(String[] args) {
// TODO code application logic here
if(args.length==0)
new TransferClient("127.0.0.1"wink;
else
new TransferClient(args[0]);
}

}

(1) (Reply)

Hash Analytic Internship (A Possible Scam) / Asp.net Mvc4 Help!! / How Do I Fix "Player.exe Has Stopped Working" Error Message.

(Go Up)

Sections: politics (1) business autos (1) jobs (1) career education (1) romance computers phones travel sports fashion health
religion celebs tv-movies music-radio literature webmasters programming techmarket

Links: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10)

Nairaland - Copyright © 2005 - 2024 Oluwaseun Osewa. All rights reserved. See How To Advertise. 39
Disclaimer: Every Nairaland member is solely responsible for anything that he/she posts or uploads on Nairaland.