[Editing to explain this posted question is not a duplicate of the quoted question::
The structure, details and routines in the code in the quoted question is very different from mine. In addition, (s)he is sending multiple files and using arraylist in the core. While my code sends one file at a time and I never used arraylist in the core. So what is causing my occasional block may not overlap with the problems with his/her own code
In the first answer, EJP said "You are reading the socket until read() returns -1." I did not do this in my code
In the first answer, EJP said "You need to send the file size ahead of each file. You're already doing a similar thing with the file count. Then make sure you read exactly that many bytes for that file:" I already send exact file size ahead of the file sent in my original posted code so this is not a problem with my code and thus not the solution to the problem i face
The code in the second answer (in the quoted duplicate) serves a different purpose and thus I cannot extrapolate a solution from it to my own code.
The quoted question says "The subsequent files are created in the server folder, but they are 0 bytes" This is not a problem with my own code. When my code runs i receive full file bytes at both client and server ends.
Over all I have read through both the quoted question and the solutions provided and they do not provide any solutions to the problems I faced
thank you]
I am relatively new to client server coding. I have Android as client and Java server. The system at the moment works like this:: Android client selects/loads a Jpeg image from sdcard, sends int size, string text and image file to server and server sends back integer and a text file with data back to client
My problem at the moment it works perfectly (randomly) only roughly ~60% of the runs. The remainder of the time it blocks permanently and I have to restart server to continue. [Certainly, a little over half of the time, the client-server system sends and receives without a glitch, but ~40% to 45% (permanent block) failure rate is unacceptable]
When it blocks there is no crash dump, stacktrace or error to read. I have searched previous similar blocking questions and tried to close sockets and inputstream/outputstream and wrappers in different orders varying the permutations, but the success/permanent block rate remained the same
Because there is no stack trace and the randomness, I have no clue what causes the block. Except that using print statements all the server and client code the last prints that hang permanently is in the bytes receiving do-while loop in the server code
I am at a loss on what to do to solve this. I'm hoping experienced minds in this field would help solve this. Full code is below.
Java Server code
public class FileServer {
public static void main(String[] args) throws IOException {
int bytesRead;
int current = 0;
//===============================================
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
//==============================================
InetAddress IP=InetAddress.getLocalHost();
servsock = new ServerSocket(57925);
System.out.println("IP "+IP.getHostAddress()+" ***%% :"+servsock.getLocalPort());
while (true) {
sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
InputStream is = sock.getInputStream();
//=========================================================
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
//=================== read integer from client ============
String number = br.readLine();
System.out.println("integer received from client is "+String.valueOf(number));
byte [] mybytearray = new byte [Integer.valueOf(number)];
//=================== read filename string =====================================
String filename = br.readLine();
System.out.println("integer received from client is "+filename);
//===================== read file data stream bytes ================================
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
System.out.println("1 bytesRead "+bytesRead+" mybytearray.length "+mybytearray.length);
do {
bytesRead = is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
System.out.println("2 current "+current+" bytesRead "+bytesRead);
} while(current < Integer.valueOf(number));
//============================== initialise filename ======================
FileOutputStream fos = new FileOutputStream("C:\\Server root folder\\"+filename+".jpg");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//========================== write bytes to server HDD =======================
bos.write(mybytearray, 0 , current);
System.out.println("4 current "+current);
bos.flush();
long end = System.currentTimeMillis();
// System.out.println("AT SERVER: bytesRead "+bytesRead+" current "+current);
// bos.close();
// ======================== write to-be-rendered data to text file ======================
File pathPlusfile = new File("C:/Server root folder/"+filename+".txt");
appendToFile( pathPlusfile, "file name:: "+filename+"* *", 20999 );
/**/ //================== Send Data in text file to Client ============================================
// send file
mybytearray = new byte [(int)pathPlusfile.length()];
fis = new FileInputStream(pathPlusfile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
//===============================================
os = sock.getOutputStream();
//=========================== send integer to client ===============
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
number = Integer.toString(mybytearray.length);
String sendMessage = number + "\n";
bw.write(sendMessage);
bw.flush();
//========================== send file to client ===================
System.out.println("Sending " + filename + "(" + mybytearray.length + " bytes)");
os.write(mybytearray,0,mybytearray.length);
os.flush();
//========================= close =================================
System.out.println("number "+number);
System.out.println("Done.");
bos.close();
bw.close();
osw.close();
os.close();
// fos.close();
// bis.close();
// fis.close();
// br.close();
isr.close();
is.close();
closeFile( );
// servsock.close();
// sock.close();
}
}
BufferedReader bufferedReader = null;
String stringObjectData = "";
public int numFromFile = 0;
static BufferedWriter bufferedWriter = null;
public static void appendToFile( File myPathPlusFile, String S, int num ){
try{
bufferedWriter = new BufferedWriter(new FileWriter(myPathPlusFile, true));
bufferedWriter.append( S );
bufferedWriter.append( " " );
bufferedWriter.append( Integer.toString(num) );
bufferedWriter.newLine();
bufferedWriter.flush();
}
catch (IOException e){
e.printStackTrace();
}
}
public static void closeFile( ){
try{
bufferedWriter.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Android Client code
public class FSendfileActivity extends Activity {
private static final int SELECT_PICTURE = 1;
private Socket sock;
private String serverIP = "192.168.1.4";
private String selectedImagePath;
private ImageView img;
final static String qcd = "qcd";
String ImageDir2Client;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Button send;
//====================
public static String FILE_TO_RECEIVED=null;
String cFilename = null;
int bytesRead = -1;
int current = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fsendfile);
ImageDir2Client = Environment.getExternalStorageDirectory().getAbsolutePath();
cFilename = "fromServer000019ggg";
FILE_TO_RECEIVED = ImageDir2Client + "/client root/"+cFilename+".txt";
img = (ImageView) findViewById(R.id.ivPic);
((Button) findViewById(R.id.bBrowse)).setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult( Intent.createChooser( intent, "Select Picture" ), SELECT_PICTURE );
}
});
send = (Button) findViewById(R.id.bSend);
send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
new Thread(new Runnable() {
@Override
public void run() {
try {
sock = new Socket();
connection(sock, serverIP, 57925);
//=================== prepare buffer to read file ====================
File myFile = new File (selectedImagePath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
//=============== read file from sdcard to buffer ==========
bis.read(mybytearray,0,mybytearray.length);
//=================================================================
OutputStream os = sock.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//============================= send size integer ===================
String number = Integer.toString(mybytearray.length);
String sendMessage = number + "\n";
bw.write(sendMessage); // send size integer here
//============================= send file name =====================
String sendMessage2 = cFilename + "\n";
bw.write(sendMessage2); // send size filename here
osw.flush();
bw.flush();
//==================================================================
os.write(mybytearray,0,mybytearray.length); // send file
os.flush();
//================= client receiving data ==============================
InputStream is = sock.getInputStream();
//=================== read integer from client ==========
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
number = br.readLine();
//========================= set incoming file size=============================
mybytearray = new byte [Integer.valueOf(number)];
//========================read file bytes in chunks===============================
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead = is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(current < Integer.valueOf(number));
fos = new FileOutputStream(FILE_TO_RECEIVED);
bos = new BufferedOutputStream(fos);
bos.write(mybytearray, 0 , current);
bos.flush();
try{
bos.close();
osw.close();
os.close();
// fos.close();
// bw.close();
// br.close();
// isr.close();
bis.close();
sock.close();
// fis.close();
}
catch(Exception e){
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try{
}
catch(Exception e){
e.printStackTrace();
}
}
}
}).start();
}
});
}
public static void connection(Socket s, String serverIP, int port) {
try {
Log.v(qcd, " before connecting ****...");
s.connect(new InetSocketAddress(serverIP, port), 120000);
Log.v(qcd, " socket connection DONE!! ");
} catch (UnknownHostException e) {
e.printStackTrace();
Log.v(qcd, " Unknown host..."+e);
} catch (IOException e) {
e.printStackTrace();
Log.v(qcd, " Failed to connect... "+e);
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
img.setImageURI(null);
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
TextView path = (TextView) findViewById(R.id.tvPath);
path.setText("Image Path : " + selectedImagePath);
img.setImageURI(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}