Can anyone let me know what is wrong in the below code.. Why is it not executing the while loop block?
I have the necessary permissions in the manifest file.
public class MainActivity extends Activity {
static TextView t;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t=(TextView)findViewById(R.id.txt);
NetConnect th=new NetConnect();
th.start();
}
public class NetConnect extends Thread {
public void run(){
try{
runOnUiThread(new Runnable(){public void run(){t.append("Thread start...");}});
Socket client = new Socket("time-b.nist.gov", 13);
BufferedReader in =new BufferedReader(new InputStreamReader(client.getInputStream()));
String str;
while((str=in.readLine())!=null)
t.append(str);
}catch(Exception e){
Log.e("Internet:",e.toString());
}
}
}
There seems to be a problem with "time-b.nist.gov". I tried the following simple socket example in a java project (to simplify against creating an Android project):
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestSocketClass {
public static void main(String[] args) {
String hostname = "time-b.nist.gov";
try {
Socket theSocket = new Socket(hostname, 13);
InputStream timeStream = theSocket.getInputStream();
StringBuffer time = new StringBuffer();
int c;
while ((c = timeStream.read()) != -1)
time.append((char) c);
String timeString = time.toString().trim();
System.out.println("It is " + timeString + " at " + hostname);
} // end try
catch (UnknownHostException ex) {
System.err.println(ex);
} catch (IOException ex) {
System.err.println(ex);
}
}
}
Nothing returned if String hostname = "time-b.nist.gov";:
It is at time-b.nist.gov
but if I change it to String hostname = "time.nist.gov"; I get:
It is 56438 13-05-26 11:49:57 50 0 0 809.9 UTC(NIST) * at
time.nist.gov
Related
I am sending a Collection(NetworkObject) via ObjectInput and Outputstreams to a server and he receives them without a problem, but he can't read the response which should be a string(also object now for testing). But the app keeps telling me the socket is closed.
Thanks in advance.
My whole Activity
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.example.cl.BasicActivity;
import com.example.cl.data.NetworkObject;
import com.example.cl.R;
import com.example.cl.data.Produkt;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import static java.lang.Thread.sleep;
public class ServerHandler extends BasicActivity implements View.OnClickListener {
public static final int SERVERPORT = 26000;
public static final String SERVER_IP = "192.168.1.2";
//public static final String SERVER_IP = "192.168.0.206";
private ClientThread clientThread;
private Thread thread;
private LinearLayout msgList;
private Handler handler;
private int clientTextColor;
private EditText edMessage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connect);
setTitle("Client");
clientTextColor = ContextCompat.getColor(this, R.color.green);
handler = new Handler();
msgList = findViewById(R.id.msgList);
edMessage = findViewById(R.id.edMessage);
}
public TextView createLine(String message, int color) {
if (null == message || message.trim().isEmpty()) {
message = "<Empty Message>";
}
TextView tv = new TextView(this);
tv.setTextColor(color);
tv.setText(message );
tv.setTextSize(20);
tv.setPadding(0, 5, 0, 0);
return tv;
}
public void showMessage(final String message, final int color) {
handler.post(new Runnable() {
#Override
public void run() {
msgList.addView(createLine(message, color));
}
});
}
#Override
public void onClick(View view) {
if (view.getId() == R.id.connect_server) {
msgList.removeAllViews();
showMessage("Connecting to Server...", clientTextColor);
clientThread = new ClientThread();
thread = new Thread(clientThread);
thread.start();
return;
}
if (view.getId() == R.id.send_data) {
String clientMessage = edMessage.getText().toString().trim();
showMessage(clientMessage, Color.BLUE);
if (null != clientThread) {
clientThread.sendMessage(clientMessage);
}
}
if (view.getId() == R.id.send_elem) {
if (null != clientThread) {
clientThread.sendElem(/*bestellung*/);
}
}
}
class ClientThread implements Runnable {
private Socket socket;
//private BufferedReader input;
private ObjectInputStream ois;
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
//sleep(250);
if (socket != null)
showMessage("Connected to Server!", clientTextColor);
while (!Thread.currentThread().isInterrupted()) {
//this.input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
//ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
//String message = input.readLine();
NetworkObject networkObject = (NetworkObject) ois.readObject();
/*
if (null == message || "Disconnect".contentEquals(message)) {
Thread.interrupted();
message = "Server Disconnected.";
showMessage(message, Color.RED);
break;
}
*/
showMessage("Server: " + networkObject, clientTextColor);
// showMessage("Server: " + message, clientTextColor);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException | ClassNotFoundException e1) {
e1.printStackTrace();
}
}
void sendMessage(final String message) {
new Thread(new Runnable() {
#Override
public void run() {
try(ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));) {
if (null != socket) {
oos.writeUTF(message);
oos.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
void sendElem(/*NetworkObject networkObject*/) {
new Thread(new Runnable() {
#Override
public void run() {
try(ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));) {
if (null != socket) {
Produkt produkt = new Produkt("Bier","Zipfer",16,3.50,1,true);
List<Object> produktList = new LinkedList<>();
produktList.add(produkt);
produktList.add(produkt);
NetworkObject networkObject = new NetworkObject("order",46020849,1,produktList);
showMessage(networkObject.toString(), Color.BLUE);
oos.writeObject(networkObject);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (null != clientThread) {
clientThread.sendMessage("Disconnect");
clientThread = null;
}
}
}
The thread in the Clienthandler which should read it also contains the sending methods but they should work.
private Socket socket;
//private BufferedReader input;
private ObjectInputStream ois;
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
//sleep(250);
if (socket != null)
showMessage("Connected to Server!", clientTextColor);
while (!Thread.currentThread().isInterrupted()) {
//this.input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
//ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
//String message = input.readLine();
NetworkObject networkObject = (NetworkObject) ois.readObject();
/*
if (null == message || "Disconnect".contentEquals(message)) {
Thread.interrupted();
message = "Server Disconnected.";
showMessage(message, Color.RED);
break;
}
*/
showMessage("Server: " + networkObject, clientTextColor);
// showMessage("Server: " + message, clientTextColor);
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException | ClassNotFoundException e1) {
e1.printStackTrace();
}
}
The error I get
W/System.err: java.net.SocketException: Socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:119)
at java.net.SocketInputStream.read(SocketInputStream.java:176)
at java.net.SocketInputStream.read(SocketInputStream.java:144)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:248)
W/System.err: at java.io.BufferedInputStream.read1(BufferedInputStream.java:288)
at java.io.BufferedInputStream.read(BufferedInputStream.java:347)
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2454)
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2470)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2947)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:858)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:353)
at com.example.cl.serverKom.ServerHandler$ClientThread.run(ServerHandler.java:131)
at java.lang.Thread.run(Thread.java:919)
I have a class to download a file (PortParser) class. and after setting the debugger inside doInBackground method. I can see after calling execute, it jumps to the next line in MainActivity instead of going inside doInBackground. what could this be. I can see the program going inside the execute method which in turn calls the AsyncTask execute method. but it never goes inside doInBackground method. Thanks.
this is the calling instance inside main activity class
portParser = new PortParser(this.getApplicationContext());
portParser.execute();
package org.pctechtips.netdroid.classes;
import android.os.AsyncTask;
import android.content.Context;
import android.util.*;
import org.pctechtips.netdroid.dbhelper.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.util.zip.*;
import javax.net.ssl.*;
/**
* Java class to downloand and parse service-port csv file from iana.org
*/
public class PortParser {
//public static final String PORT_URL = "https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.csv";
public static final String PORT_URL = "http://pctechtips.org/apps/service-names-port-numbers.csv";
org.pctechtips.netdroid.dbhelper.DatabaseHelper dbHelper;
DownloadPortFile downloadFile;
android.database.sqlite.SQLiteDatabase db;
Context context;
public PortParser(Context ctxt) {
dbHelper = new org.pctechtips.netdroid.dbhelper.DatabaseHelper(ctxt);
db = dbHelper.getWritableDatabase();
downloadFile = new DownloadPortFile();
}
public void execute() {
Log.v("DOWNLOADING", "DOWNLOADING PORT FILE");
downloadFile.execute();
}
public class DownloadPortFile extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
BufferedReader in = null;
HttpsURLConnection connection = null;
try {
URL url = new URL(PORT_URL);
connection = (HttpsURLConnection) url.openConnection();
// connection.setRequestProperty("Accept-Encoding", "gzip");
connection.connect();
Log.v("CONNECTION", "CONNECTION OK");
if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
Log.v("CONNECTION", "CONNECTION OK");
}
in = new BufferedReader(new InputStreamReader(new GZIPInputStream(connection.getInputStream()), "UTF-8"));
String line;
int lineNum = 0;
while ((line = in.readLine()) != null) {
String[] data = line.split(",", -1);
Log.v("DATA", Arrays.toString(data) +" "+ lineNum);
if(data.length != 12) { continue; }
if(data == null) { continue; }
if(!data[2].equalsIgnoreCase("tcp")) { continue; }
String service = (data[0].equals(" ")) ? "null" : data[0];
int portNum = Integer.parseInt(data[1]);
String protocol = data[2];
String desc = data[3];
Log.v("PARSED", service +" "+ portNum +" "+ protocol +" "+ desc +" "+data.length);
long dbInsert = dbHelper.addTableRecord(service, portNum, protocol, service);
}
} catch (Exception e) {
} finally {
/*try {
if (in != null) {
in.close();
}
} catch (IOException ignored) {
}
if (connection != null) {
connection.disconnect();
}*/
}
return null;
}
#Override
protected void onProgressUpdate(Void... voids) {
}
#Override
protected void onPostExecute(Void aVoid) {
}
}
}
I can see after calling execute, it jumps to the next line in MainActivity instead of going inside doInBackground
This is how it should be as there's no reason for main thread flow to be disrupted just because you spawned other asynchronous worker. That would be actually contrary to what async things are for. If you want to debug doInBackground() you should set a breakpoint on that method's code somewhere (+ you may need to call Debug.waitOnDebugger() if just breakpoint won't work).
The app has MainActivity(contains an EditText and a Button) and DisplayActivity(contains a single TextView)The user enters a message in the EditText and presses the send button. The message string from the EditText gets sent to the server. Then starts a new intent to DisplayActivity. DisplayActivity will read data from the server with readLine(), and set TextView from the data received from the server.
activity_main.xml has a EditText with id="#+id/message_textView" and Button with id="#+id/send_button". DisplayActivity has android:id="#+id/displayTextView".
My code to send data to the server works, but when I try to read data from the server, readline() just stops there and sits there forever.
Android app has MainActivity and DisplayActivity class.
I run the server code in eclipse.
Server code.
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.net.*;
import java.io.*;
public class MyServer {
public static void main(String[] args) throws IOException {
int portNumber = 4442;
System.out.println("Starting server..");
try {
while(true) {
ServerSocket serverSocket =
new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String message = in.readLine();
System.out.println(message);//Just print to console, to test if server got message
out.println(message);
serverSocket.close();
clientSocket.close();
// out.close();
// in.close();
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
MainActivity
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
static Socket client;
private PrintWriter printWriter;
private EditText messageET;
private Button sendButton;
private String message;
static String hostIP = "10.0.2.2";
static int port = 4442;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
messageET = findViewById(R.id.message_textView);
sendButton = findViewById(R.id.send_button);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
message = messageET.getText().toString();
messageET.setText("");
MyTask myTask = new MyTask();
myTask.execute();
Intent intent = new Intent(getApplicationContext(), DisplayActivity.class);
startActivity(intent);
}
});
}
class MyTask extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... strings) {
try
{
client = new Socket(hostIP, port);
printWriter = new PrintWriter(client.getOutputStream(), true);
//printWriter.write(message);
printWriter.println(message);
//printWriter.flush();
printWriter.close();
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
return null;
}
}
}
DisplayActivity
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class DisplayActivity extends AppCompatActivity {
//final String TAG = "displayactivitylog";
private Socket socket;
private BufferedReader bufferedReader;
private TextView displayTV;
private String msgReceived = null;
String hostIP = "10.0.2.2";
int port = 4442;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display);
displayTV = findViewById(R.id.displayTextView);
ReadTask readTask = new ReadTask();
readTask.execute();
}
class ReadTask extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... strings) {
String result = "";
try
{
//create a new socket and attempt to read from it
socket = new Socket(hostIP,port);
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//*****the app stops on this line, and nothing happens after*****
msgReceived = bufferedReader.readLine();
//************************************
// while((msgReceived = bufferedReader.readLine()) != null){
// result += msgReceived;
// }
bufferedReader.close();
socket.close();
}catch(IOException e)
{
e.printStackTrace();
}
return result;
}
//update the TextView with the message from the server
#Override
protected void onPostExecute(String s) {
displayTV.setText(s);
super.onPostExecute(s);
}
}
}
When i run debugger, it literally just stops in DisplayActivity.java on msgReceived = bufferedReader.readLine() in the doInBackground() method and gives no error.
My server starts fine and when I send data from my app to the server, on eclipse it prints out what was sent(and sometimes null for some reason).
---------------SOLUTION---------------
Question was answered by green apps, but basically the server class expects to read something when a connection first opens, and then send out data. However in ReadTask, all it does is try to read data from the server(but it should send data first, then read from it)
Updated code.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private EditText messageET;
private Button sendButton;
static String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
messageET = findViewById(R.id.message_textView);
sendButton = findViewById(R.id.send_button);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
message = messageET.getText().toString();
messageET.setText("");
Intent intent = new Intent(getApplicationContext(), DisplayActivity.class);
startActivity(intent);
}
});
}
}
DisplayActivity.java
public class DisplayActivity extends AppCompatActivity {
private Socket socket;
private PrintWriter printWriter;
private BufferedReader bufferedReader;
private TextView displayTV;
private String msgReceived = null;
String hostIP = "10.0.2.2";
int port = 4442;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display);
displayTV = findViewById(R.id.displayTextView);
ReadTask readTask = new ReadTask();
readTask.execute();
}
class ReadTask extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... strings) {
String result = "";
try
{
//create a new socket and attempt to write to it first then read from it
socket = new Socket(hostIP,port);
//add data to the server
printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(MainActivity.message);
//get a stream, to be able to read data from the server
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
msgReceived = bufferedReader.readLine();
displayTV.setText(msgReceived);
//close the socket connections
printWriter.close();
bufferedReader.close();
socket.close();
}catch(IOException e)
{
e.printStackTrace();
}
return result;
}
}
}
You have two clientsocketss. And two serversockets.
Which is a very strange approach.
The first client sends a line and closes the connection. This works ok as the server tries to read that line and does. Both then close.
Then you start the second client. This one connects to a new serversocket. But this client directly tries to read a line. As the server also tries to read a line from this new client both will wait for eternity on readLine().
I' working on an app which among other things preforms a port scan. My problem is that I'm trying to implement a progress bar as the scan takes place. Right now I use AsynTask to perform the scan. But how can I update the progress bar while the scan is performing? Can I use the same AsynTask for both task or I need to implement a separate one. Any help appreciate!
PortScanActivity
package com.example.android.droidscanner;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
/**
* Created by jlvaz on 3/7/2017.
*/
public class PortScanActivity extends AppCompatActivity{
String ipAddress;
ArrayList<String> openPorts;
ArrayAdapter<String> portAdapter;
int startPort = 0;
int endPort = 1023;
TextView statusMsg;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scan_list);
Intent portIntent = getIntent();
ipAddress = portIntent.getStringExtra("host");
statusMsg = (TextView) findViewById(R.id.status_msg);
//setting the adapter
ListView portList = (ListView) findViewById(R.id.scan_list);
openPorts = new ArrayList<>();
portAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, openPorts);
portList.setAdapter(portAdapter);
//scanning ports
PortScanTask portScan = new PortScanActivity.PortScanTask();
portScan.execute();
}
private class PortScanTask extends AsyncTask<Void, String, Void> {
int timeOut = 1000; //for how long try connection in ms
#Override
protected void onPreExecute() {
openPorts.clear();
statusMsg.setText("Scanning " + ipAddress + " ports..");
}
#Override
protected Void doInBackground(Void... params) {
for (int i = startPort; i <= endPort; i++) {
try {
//establishing connection to every port
Socket socket = new Socket();
SocketAddress address = new InetSocketAddress(ipAddress, i);
socket.connect(address, timeOut);
Log.v("Connecting to: ", ipAddress + i);
if (socket.isConnected()) {
socket.close();
publishProgress(ipAddress + ": " + i);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (ConnectException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
openPorts.add(values[0]);
portAdapter.notifyDataSetInvalidated();
Toast.makeText(getApplicationContext(), values[0].toString() + " open!", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(Void aVoid) {
statusMsg.setText("Scan Complete!");
}
}
}
On progress update pass your custom class object which contains both, the string and the progress integer.
class ProgressStep {
int progress;
String address;
}
private class PortScanTask extends AsyncTask<Void, ProgressStep, Void> {
int timeOut = 1000; //for how long try connection in ms
#Override
protected void onPreExecute() {
openPorts.clear();
statusMsg.setText("Scanning " + ipAddress + " ports..");
}
#Override
protected Void doInBackground(Void... params) {
for (int i = startPort; i <= endPort; i++) {
try {
//establishing connection to every port
Socket socket = new Socket();
SocketAddress address = new InetSocketAddress(ipAddress, i);
socket.connect(address, timeOut);
Log.v("Connecting to: ", ipAddress + i);
int progress = count_your_progress;
ProgressStep step = new ProgressStep();
step.progress = progress;
if (socket.isConnected()) {
socket.close();
String address = ipAddress + ": " + i;
step.address = address;
}
publishProgress(step);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (ConnectException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(ProgressStep... values) {
ProgressStep step = values[0];
if (step.address != null) {
openPorts.add(step.address);
portAdapter.notifyDataSetInvalidated();
Toast.makeText(getApplicationContext(), step.address + " open!", Toast.LENGTH_SHORT).show();
}
progressBar.setProgress(step.progress);
}
#Override
protected void onPostExecute(Void aVoid) {
statusMsg.setText("Scan Complete!");
}
}
I am implementing socket programming in android. I am successfully getting data from client and displaying it to the server.
The asynctask is as follows:
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice:
* inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
The above code gets data from server and write it to the text view. I want to use the same socket to get data multiple times from server, unless a particular button is clicked. But, in doInBackground, we can't use any ui component. I want to change the following component, so that I can recieve multiple data from the server:
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice:
* inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1){
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
I tried to use
onProgressUpdate
but it didn't work either. Please help me to solve this.
Edit 1: the client's main activity :
package com.example.shiza.client;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "CLIENT_MESSAGE";
EditText ip_address;
EditText port_number;
EditText message_client;
Button button_send;
Button button_cancel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void connect(View view) {
// ip_address = (EditText) findViewById(R.id.ip_address);
// ip_address.setText("192.168.9.100");
// port_number = (EditText) findViewById(R.id.port_number);
// port_number.setText("8080");
message_client = (EditText) findViewById(R.id.message_client);
button_send = (Button)findViewById(R.id.button_send);
button_cancel = (Button)findViewById(R.id.button_cancel);
Log.d(TAG, "connecting to the server.");
// new ConnectToServer(ip_address.getText().toString(), port_number.getText().toString(), message_client,button_send,button_cancel).execute();
new ConnectToServer("192.168.9.100","8080", message_client,button_send,button_cancel).execute();
}
}
class ConnectToServer extends AsyncTask<Void, DataOutputStream, Void> {
private static final String TAG = "CLIENT_MESSAGE";
String ip_address;
int port_number;
EditText message_client;
Button button_send;
Button button_cancel;
boolean send = false;
boolean cancel = false;
public ConnectToServer(String ip_address, String port_number, EditText message_client,Button button_send,Button button_cancel) {
this.ip_address = ip_address;
this.port_number = Integer.parseInt(port_number);
this.message_client = message_client;
this.button_cancel = button_cancel;
this.button_send = button_send;
}
#Override
protected Void doInBackground(Void... params) {
try {
Socket socket = new Socket(ip_address, port_number);
if (LoggerConfig.TAG) {
Log.d(TAG, "the socket is created at " + ip_address);
}
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
while (!cancel )
publishProgress(output);
// output.writeUTF("Hello from string");
if (LoggerConfig.TAG) {
Log.d(TAG, "I have written and closed the loop.");
}
socket.close();
} catch (IOException e) {
if (LoggerConfig.TAG) {
Log.d(TAG, "Could not connect.");
}
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(DataOutputStream... values) {
super.onProgressUpdate(values);
button_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
send = true;
}
});
button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cancel = true;
}
});
Log.d(TAG, "I am in onProgressUpdate");
if ( send )
{
try {
values[0].writeUTF(message_client.getText().toString());
Log.d(TAG, "I am in onProgressUpdate try.");
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "I am in onProgressUpdate catch.");
}
send = false;
}
}
}
The server's main activity:
package com.example.shiza.server;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
TextView ip_address;
TextView client_message;
TextView server_status;
TextView show_client_message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ip_address = (TextView) findViewById(R.id.ip_address);
client_message = (TextView) findViewById(R.id.get_client_message);
server_status = (TextView) findViewById(R.id.server_status);
show_client_message = (TextView) findViewById(R.id.show_client_message);
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
ip_address.setText(ip);
// Making a server socket here
}
public void startServer(View view) {
GetFromClient getFromClient = new GetFromClient(this,server_status,show_client_message);
getFromClient.execute();
}
}
class GetFromClient extends AsyncTask<Void, String, Void> {
Context context;
TextView server_status;
TextView show_client_message;
String TAG = "SERVER_MESSAGE";
String inputFromClient = null;
public GetFromClient(Context context,TextView server_status,TextView show_client_message) {
this.context = context;
this.server_status = server_status;
this.show_client_message = show_client_message;
}
#Override
protected Void doInBackground(Void... params) {
Socket socket;
try {
ServerSocket serverSocket = new ServerSocket(8080);
Log.d(TAG, "Server Socket is starting....");
// server_status.setText("The server is running");
publishProgress("okay");
socket = serverSocket.accept();
DataInputStream input = new DataInputStream(socket.getInputStream());
// Calling the second background task for handling input from server
// Log.d(TAG, "Server Socket is started....");
do
{
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
inputFromClient = input.readUTF();
publishProgress(inputFromClient);
}
while ( inputFromClient != "bye" );
// publishProgress(2);
socket.close();
} catch (IOException e) {
Log.d(TAG, "I am in catch.");
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
Log.d(TAG, "I am in onProgress update.");
if ( values[0].equals("okay") )
{
server_status.setText("Server has been started");
server_status.setTextColor(context.getResources().getColor(R.color.green));
}
else
{
show_client_message.setText(values[0]);
}
}
protected void onPostExecute(Void inputFromClient)
{
Log.d(TAG, "I am in onPostExecute.");
server_status.setText("Server is not running");
server_status.setTextColor(context.getResources().getColor(R.color.red));
}
}
I am able to do the messaging but the following loop blocks everything:
do
{
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
inputFromClient = input.readUTF();
publishProgress(inputFromClient);
}
while ( inputFromClient != "bye" );
You can update your TextView in the doInBackground method using RunUiThread. After receiving the data from server just call
runOnUiThread(new Runnable() {
#Override
public void run() {
//here you update the views
}
});