In my android app I'm creating a Socket and a BufferedReader. If i just read one line of the BufferedReader I'm getting the response from the server. But if I'm trying it with while((message = br.readLine()) != null) The application crashes. Any ideas what could be the problem?
Code
public void connecting(String uid) {
uuid = uid;
try {
client = new Socket("127.0.0.1", 8234);
try {
tv = (TextView) chat.findViewById(R.id.textView);
pw = new PrintWriter(client.getOutputStream());
br = new BufferedReader(new InputStreamReader(client.getInputStream()));
new Thread(new Runnable() {
#Override
public void run() {
try {
// If i just try this, it works
tv.append("\n"+br.readLine());
// If I'm trying this, it crashes
String message = "";
while((message = br.readLine()) != null) {
tv.append("\n"+message);
}
} catch (IOException e) {
tv.append(e.getMessage());
}
}
}).start();
tv.append("Connected!");
pw.println(uuid+":B31TR1TT");
pw.flush();
} catch (IOException e) {
tv.append(e.getMessage());
}
} catch (IOException e) {
tv.append(e.getMessage());
}
}
As algui91 said move the network calls to a separate thread. that strict mode error (violation=4) indicates network calls on ui thread.
Just refactor the network calls into a background task (service, asynctask , or whaetever ) , and the issue should go away.
Separate the UI from the business logic or network communication. Its always better and easier to test/debug.
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
Instead of while loop code try to use this code
or visit this link http://hastebin.com/inecerakes.java
Related
There is such a problem. To transfer files in an Android application, we use a Socket, we encrypt and transfer to the server, there the data is decrypted and transmitted by the usual POST method, but when some data is transferred, the file is not loaded, but returns 500 The error stream terminated unexpectedly. One xlsx file is transferred. but the other is gone. We also saw that if the file is still uploaded to the server and we download it, the file is broken and at the end a piece of header Content-Disposition: form-data; name = "publicAccess" false.
ANDROID CODE
#Override
public void run() {
try {
byte[] request = new byte[4096];
byte[] reply = new byte[8192];
final InputStream inFromClient = sClient.getInputStream();
final OutputStream outToClient = sClient.getOutputStream();
SSLSocket remoteSocket = tlsConnectionService.createSSLSocket(remoteHost, remotePort);
final InputStream inFromServer = remoteSocket.getInputStream();
final OutputStream outToServer = remoteSocket.getOutputStream();
// a new thread for uploading to the server
new Thread() {
public void run() {
int bytes_read;
try {
while ((bytes_read = inFromClient.read(request)) != -1 ) {
String newReq = new String(request);
if (newReq != null) {
outToServer.write(newReq.replace(LOCAL_SOCKET_URL, remoteHost).getBytes(), 0, bytes_read);
outToServer.flush();
}
}
} catch (IOException e) {
if (!(e instanceof SocketException)) {
Log.e(M.CPP, e.toString());
}
}
}
}.start();
// current thread manages streams from server to client (DOWNLOAD)
int bytes_read;
try {
while ((bytes_read = inFromServer.read(reply)) != -1 ) {
outToClient.write(reply, 0, bytes_read);
outToClient.flush();
}
} catch (IOException e) {
Log.e(M.CPP, e.toString());
} finally {
try {
remoteSocket.close();
} catch (IOException e) {
Log.e(M.CPP, e.toString());
}
}
sClient.close();
} catch (IOException e) {
Log.e(M.CPP, e.toString());
}
}
Server CODE
#PostMapping(
value = {"/file", "/file/" },
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public ResponseEntity<FileEntryDto> upload(
#PathVariable("source") String source,
#AuthenticationPrincipal JwtUserDetails currentUser,
#Validated FileUploadRequest request
) {
return ResponseEntity.ok(
converters.fileToDto(
fileOperationService.upload(Source.fromName(source), request, currentUser.getUserId()))
);
}
The request that we see when inspecting app
request
Hi I am trying to implement server operating with multiply clients
The problem is that the server does not receive the message from inputstream and wait until it happen. if the client don't close the stream after writing to it the server will continue to wait. After the client send the message, he try to read from the inputstream waiting for response, but the server is waiting for the request. So.. deadlock
This is my client class
public class Client implements Runnable{
...
#Override
public void run() {
BufferedReader is = null;
BufferedWriter os = null;
try(Socket socket = new Socket(address.getHostName(), address.getPort());){
String request = String.format("%s-%d-%s",this.destination, this.desiredPlace, this.paymentMethod.toString());
os = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(os, true);
pw.write(request);
pw.flush();
// if I close the stream here the request will be send, but this will close the socket so the I will not receive response.
String response;
while ((response = is.readLine()) != null){
System.out.println(response);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And this is my server class
public void perform() throws IOException, DestionationProcessingException, InterruptedException {
try (ServerSocket server = new ServerSocket(port);) {
StandalonePayDesk offLinePayDesk = new StandalonePayDesk(ticketManager);
this.threadPool.submit(offLinePayDesk);
while (true) {
Socket socket = server.accept();
RequestHandler handler = new RequestHandler(this.threadPool, offLinePayDesk, this.ticketManager);
handler.process(socket);
}
}
}
and RequestHandler class for processing each client
try (BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter writer = new PrintWriter(client.getOutputStream(), true)) {
writer.println("hello");
writer.flush();
String line;
while ((line = reader.readLine()) != null) {
String[] lineTokens = line.split("-");
...
Can anyone help me to solve this problem ?
pw.write(request);
Your client is writing a request but not a line. Your server is reading a line, with readLine(), and will block until the line terminator arrives, which is never, so it will never send a reply, so your client will never receive it, so it will block forever.
Change the above to:
pw.println(request);
I have an android process that I start. It is a getevent command. This (when ran in a console) gives continuous event occurances. I wish to collect these within an Android app. My current way of doing this will effectively collect "one off" process outputs but I can't seem to find a way of storing the continuous results from the getevent method as they occur.
The current code I have for this is the following. It works for things like "ls" but not for continuous streams such as "getevent".
try {
Process chmod = Runtime.getRuntime().exec("getevent -lt /dev/input/event1");
BufferedReader reader = new BufferedReader(new InputStreamReader(chmod.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
chmod.waitFor();
String outputString = output.toString();
Log.d("output", outputString);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
I had the same issue. Here is how I solved it.
First I created a TimerTask to log/read continuous output in a BufferReader of either a logcat or getevent. TimerTask creates new Thread, which runs in background and doesn't interfere or block other UI handlers in service class. So I believe it is safer that way.
Then I started the TimerTask from Service class in onCreate() method.
One thing is mine device was rooted, so I start with 'su' session. I believe 'sh' session is also works for non root devices.
Service class:
public class ServiceClassPhone extends Service {
....
private GetEventRecorder getEventRecorder;
#Override
public void onCreate() {
....
getEventRecorder= new GetEventRecorder();
getEventRecorder.start();
// (if there is any) postDelay other UI handlers in service
}
And GetEventRecorder class:
public class GetEventRecorder {
....
private static Logger mLogger = new Logger();
private GetEventRecorder mRecorder = null;
Timer timer;
// active su session
private Process mProcess;
// Byte Writer
private OutputStream mStdIn;
private DataOutputStream outputStream;
private BufferedReader br;
{
try {
mProcess = Runtime.getRuntime().exec("su");
outputStream = new DataOutputStream(mProcess.getOutputStream());
String comm1 = "getevent -l";
String comm2 = "logcat -c";
String close = "^C";
String newLine= "\n";
outputStream.writeBytes(comm1);
outputStream.writeBytes(newLine);
} catch (IOException e) {
Log.d(TAG, "Could not spawn su process");
e.printStackTrace();
}
}
public void start() {
try {
timer = new Timer();
timer.scheduleAtFixedRate(new GetEventRecorder.RecorderTask(), 0, 1000);
} catch (Exception e) {
Log.d(TAG, "Exception: " + e);
}
}
public void stop() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder = null;
timer.cancel();
}
}
public void logGetEventData(){
....
}
}
private class RecorderTask extends TimerTask {
public RecorderTask() {}
#Override
public void run() {
try {
String comm1 = "getevent -l";
String comm2 = "logcat -c";
String close = "^C";
byte[] newLine = "\n".getBytes();
outputStream.writeBytes(close);
outputStream.flush();
br = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));
boolean cont=true;
String line;
Log.d(TAG,"geteventLogs BufferedReader for continuous getevent reading... " );
if (br!=null ) {
Log.d(TAG,"geteventLogs BufferedReader is not null checking for readiness... ");
if (br.ready()) {
Log.d(TAG, "BufferedReader for getevent is not null and ready");
String separator = System.getProperty("line.separator");
while ((line = br.readLine()) != null && line.contains("event0:")
&& !line.contains("BufferedReader") ) {
...
logGetEventData();
}catch (Exception e) {
if (DBG) Log.d(TAG, "getevent recorder error: " + e);
}
}
}
}
I'm using this code. Server and android app.
https://github.com/luugiathuy/Remote-Bluetooth-Android
I can send int commands but I want to send strings for more information
I create the issue in the repository but I want all the help posible
In the server I have this
#Override
public void run() {
try {
// prepare to receive data
InputStream inputStream = mConnection.openInputStream();
System.out.println("waiting for input");
while (true) {
int command = inputStream.read();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, Charsets.UTF_8);
String theString = writer.toString();
System.out.println(theString);
if (command == EXIT_CMD)
{
System.out.println("finish process");
break;
}
processCommand(command);
}
} catch (Exception e) {
e.printStackTrace();
}
}
with this response...
BlueCove version 2.1.1-SNAPSHOT on winsock
04c6093b00001000800000805f9b34fb
waiting for connection...
waiting for connection...
waiting for input
23456789?
finish process
BUT in Android I send "123456789" with this code
public void write(String out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out.getBytes());
}
Few edits...
I comment this line
int command = inputStream.read();
and I get the "full" string this this code
BufferedReader bReader=new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while ((line = bReader.readLine()) != null)
{
System.out.println(line);
}
123456789ÿ
I can eliminate the last char but is not the best...
In my android app I have this
mCommandService.write(editText.getText().toString().trim());
editText.getText().clear();
mCommandService.stop();
If I remove the last line, the ÿ disapear. So I guess that is the stop command. Can I remove that or is native?
I am trying to create simple app with android client and java server
android client is able to send message to server(java)
while when i try to read server reply
error:socket closed.
line(if((receiveMessage = receiveRead.readLine()) != null) )
public class ClientConnectorTask extends AsyncTask<String, Void, Integer> {
private Socket client;
private PrintWriter printwriter;
protected Integer doInBackground(String...strings) {
// validate input parameters
if (strings.length <= 0) {
return 0;
}
// connect to the server and send the message
try {
client = new Socket("192.168.1.4", 7777);
printwriter = new PrintWriter(client.getOutputStream(),true);
//while(true){
InputStream istream = client.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
String receiveMessage;
while (true){
// printwriter.write(strings[0]);
printwriter.print(strings[0]);
printwriter.flush();
printwriter.close();
if((receiveMessage = receiveRead.readLine()) != null) //receive from server
{
System.out.println(receiveMessage); // displaying at DOS prompt
}
}
//}
//client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
protected void onPostExecute(Long result) {
return;
}
}
Closing the PrintWriter inside the loop doesn't make sense, and closing it before the readLine() call doesn't make sense either. Closing either the input or the output stream of a Socket closes the other stream and the socket.