A few things that I'm not clear about. The first is serious, the second is a mystery and the third is an ideal state that i would like my code to run at
1. Read() function
public int read(byte[] b, int off, int len) throws IOException
This method blocks until input data is available, end of file is detected, or an exception is thrown.
Read() can block for any reason, it might be because faults in server code, user send no data at all or sends corrupted data.
If server code is well written and clear any bugs, the other two could still cause a block. And if you have many players chances are that someone somewhere will inadvertently do something stupid every so often that would cause a server block. I called this one serious (at the first line) because anytime there is a block, I've had to restart server. But it is meant to run continuously. And if the read block assumes data is still coming so it waits and blocks forever, disrupting and blocking other players.
The do-while/read() code is below, what check (code) can I add to the code that would timeout the block, without causing an exception and without needing to restart the server.
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));
2. second issue is a bit of a mystery.
In a thread, the code is supposed to run sequentially. But a line not reach can cause a issue at an earlier line. Again this happened specifically with blocking. Not closing an object in a latter code line (not reached yet) can cause a block in an earlier read() line (more often in server code)
3. My last post in the previous thread I mentioned all was now working fine. Well that was until I decided to send and receive jpeg file integers and text file with data continuously between client and server without closing either. (One cycle here means a client->server->client data transfer). It runs guaranteed in the first cycle. By the third cycle (sometimes second cycle) the application is forced stopped at the end of the run.
I don't know what causes it. The forced stopped produced no crash dump. If it did I don't know where the exception is dumped (definitely not on the console or logcat), so I can't find clues as to what the cause is. But I do need to fix this
In trying to blindly fix this (in the client code), i'm guessing some objects had been closed in the wrong order or not closed at all. But all my attempts to tweak things so far has either resulted in an exception or a block. In fact this 3rd issue is the main reason I was aware of the second issue above
How do I solve this - as in call sequences, close order, object life-time freed?
I suppose the first and third issues are the core issues i need to solve. The second is like a 3b to 3
Any ideas how I can solve the first and third problems
Many Thanks for any help
server code
public class FileServer {
public final static String FILE_RECEIVED ="C:\\rootFolder\\NEW_070075n.jpg";
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) {
System.out.println("555_999 Waiting...");
sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream(FILE_RECEIVED);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//=================== read integer from client ==========
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
System.out.println("integer received from client is "+String.valueOf(number));
byte [] mybytearray = new byte [Integer.valueOf(number)];
//=======================================================
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;
} while(current < Integer.valueOf(number));
bos.write(mybytearray, 0 , current);
bos.flush();
bos.close();
// ======================== write to-be-rendered data to text file ======================
File pathPlusfile = new File("C:/rootFolder/renderData4.txt");
appendToFile( pathPlusfile, "Hello, home joel888", 20999 );
//======================== preparing to Send Data to Client ==============================
/**/ //================== Send Data in text file to Client ============================================
// send file
// File myFile = new File (FILE_TO_SEND);
// mybytearray = new byte [(int)myFile.length()];
// fis = new FileInputStream(myFile);
//========================= send jpeg image file to client ===============================
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 ===================
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("number "+number);
System.out.println("Done.");
bis.close();
fis.close();
os.close();
fos.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.write( S );
// bufferedWriter.newLine();
bufferedWriter.append( S );
bufferedWriter.append( " " );
bufferedWriter.append( Integer.toString(num) );
bufferedWriter.newLine();
bufferedWriter.flush();
}
catch (IOException e){
e.printStackTrace();
}
// closeFile( );
}
public static void closeFile( ){
try{
// bufferedWriter.flush();
bufferedWriter.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
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;
//====================
public static String FILE_TO_RECEIVED=null;
int bytesRead = -1;
int current = 0;
public final static int FILE_SIZE = 2373620;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fsendfile);
ImageDir2Client = Environment.getExternalStorageDirectory().getAbsolutePath();
FILE_TO_RECEIVED = ImageDir2Client + "/Server root/fromServer000019eee.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 );
}
});
Button send = (Button) findViewById(R.id.bSend);
final TextView status = (TextView) findViewById(R.id.tvStatus);
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);
File myFile = new File (selectedImagePath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = sock.getOutputStream();
//=========================== send integer to server ===============
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String number = Integer.toString(mybytearray.length);
String sendMessage = number + "\n";
bw.write(sendMessage); // send size integer here
bw.flush();
//==================================================================
os.write(mybytearray,0,mybytearray.length); // send file
os.flush();
//================= client receiving data ==============================
/* */
// receive file
mybytearray = new byte [FILE_SIZE];
InputStream is = sock.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVED);
bos = new BufferedOutputStream(fos);
//=================== read integer from client ==========
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
number = br.readLine();
//=======================================================
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));
bos.write(mybytearray, 0 , current);
bos.flush();
br.close();
bis.close();
//*** bw.close();
fos.close(); //STILL EXPERIMENTING WHICH ORDER/MISSING CLOSE()
//*** bos.close(); //WOULD FIX THIRD PROBLEM MENTIONED IN ORIGINAL POST
//* isr.close();
// is.close();
// os.close();
osw.close();
fis.close();
/* */ sock.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try{
// sock.close();
}
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);
Log.v(qcd, selectedImagePath);
}
}
}
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);
}
}