Reputation: 31
Well, this is my second post and I'm going through such a big problem with socket communication TCP/IP, between android client and a java server application running on a PC.
What I try to do is send a string when I press a button from my client application to the server and then get an answer back to my client application as many times as I wish, this result is shown in a TextView
of my client.
The problem occurs when I try to connect to the server with my client application, the connection is performed successfully, but when I press the button and send the data, the client application gets stuck and the only way to show a result is stopping the server application. Please, I need help! I'm new to Android. Thanks.
This is the simple server code:
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerSocks {
private static ServerSocket myServer;
private static Socket myClient;
private static String msj_ToServer;
public static void main (String args[] ){
try {
System.out.println("Bienvenido:\n");
System.out.println("Por favor ingresar el nº de puerto de comunicación: ");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String portNumber_str = in.readLine();
int portNumber = Integer.parseInt(portNumber_str);
myServer = new ServerSocket(portNumber);
if(myServer.isBound() == true){
System.out.println("Iniciando servidor en el puerto: "+portNumber);
}
else{
System.err.println("[E R R O R] : No se pudo crear 'LISTEN SOCKET'");
System.exit(0);
}
while(true){
System.out.println("Esperando algún cliente TCP en el puerto ["+portNumber+"]...");
myClient = myServer.accept();
if (myClient.isConnected()) { // if2
System.out.println("[D A T A] : El cliente ha sido aceptado IP-CLIENT\n"+""+ "IP Client address: "+myClient.getInetAddress());
DataOutputStream outClient = new DataOutputStream(myClient.getOutputStream());
DataInputStream inClient = new DataInputStream(myClient.getInputStream());
msj_ToServer = inClient.readLine();
System.out.println("Ha1 "+msj_ToServer);
try{
if(msj_ToServer.equalsIgnoreCase("D")) {
System.out.println("HO "+msj_ToServer);
outClient.writeBytes("ON");
outClient.flush();
break;
}
}catch(IOException e){
e.printStackTrace();
}
if(msj_ToServer == "B" || msj_ToServer == "b"){
System.out.println(msj_ToServer);
outClient.writeUTF("OFF");
outClient.flush();
break;
}
if(msj_ToServer == "C" || msj_ToServer == "c"){
System.out.println(msj_ToServer);
outClient.writeUTF("xd");
outClient.flush();
break;
}
} // fin while inicio de lectura */
} // fin msj1
} // fin while prueba 3
}// fin if2
} // fin while (true) superior
} catch (IOException ex) {
Logger.getLogger(ServerSocket.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}// fin main
} // fin clase ServerSocks
This is part of the Main.java of my Android client application (I'm probing with the button ("status" button) that is sending a "D" string to the server and the server sends back an "ON" as an answer).
public class MainActivity extends Activity implements OnClickListener {
private Button ledOnButton;
private Button ledOffButton;
static ToggleButton toggleButton;
static EditText statusEditText;
private Button status;
static TextView prueba;
static Socket clientSocket;
static String data;
static String dato;
static PrintStream os;
static DataInputStream is;
static DataInputStream inputLine;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
ledOnButton = (Button) findViewById(R.id.ledOnButton);
ledOnButton.setOnClickListener(this);
ledOffButton = (Button) findViewById(R.id.ledOffButton);
ledOffButton.setOnClickListener(this);
toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
toggleButton.setOnClickListener(this);
status = (Button) findViewById(R.id.statusButton);
status.setOnClickListener(this);
statusEditText = (EditText) findViewById(R.id.statusEditText);
// prueba con textView
prueba = (TextView) findViewById(R.id.textView_Prueba);
} // fin OnCreate
@Override
public void onClick(View arg0) {
AsyncAction object = new AsyncAction();
final String salida_dato;
switch (arg0.getId()) {
case R.id.toggleButton:
if (toggleButton.isChecked()) {
object.conexion_socket();
}
if (!toggleButton.isChecked()) {
object.desconexion_socket();
}
break;
case R.id.ledOnButton:
if ((MainActivity.toggleButton.isChecked())) {
object.ledOnButton();
}
break;
case R.id.ledOffButton:
if ((toggleButton.isChecked())) {
object.ledOffButton();
}
break;
case R.id.statusButton:
here i try to send a "D" String to the server
if ((toggleButton.isChecked())) {
if (clientSocket != null && os != null && is != null) {
try {
final String responseLine;
// String data = "D";
//os.write(data.getBytes());
os.println("D");
while ((responseLine = is.readLine()) != null) {
System.out.println(responseLine);
runOnUiThread(new Runnable() {
public void run() {
MainActivity.prueba.setText(responseLine);
os.flush();
}
});
break;
}
os.close();
is.close();
clientSocket.close();
} //fin try
catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
and here the connection is running in background with asynchTasks (i think so)
@Override
protected String doInBackground(Void... args) {
conexion_socket();
...
}//fin doInBackground
and here is the connection method that i used to create the socket connection
public void conexion_socket(){
try {
MainActivity.clientSocket = new Socket("192.168.2.80", 30000);
try {
MainActivity.os = new PrintStream(MainActivity.clientSocket.getOutputStream());
MainActivity.is = new DataInputStream(MainActivity.clientSocket.getInputStream());
MainActivity.inputLine = new DataInputStream(new BufferedInputStream(System.in));
} // fin try
catch (IOException e){
System.err.println("algo anda al con los i/o ...");
} // fin catch
} catch (IOException e) {
e.printStackTrace();
}
if (MainActivity.clientSocket.isConnected()) {
MainActivity.statusEditText.setText("OK connection");
}
}
please if anyone could give a way to do this communication i would appreciate very much!
Upvotes: 3
Views: 105
Reputation: 310860
if(myServer.isBound() == true){
This cannot possibly be false at this point. Remove test and the else
block. You constructed the ServerSocket
with a port number => it is bound.
else{
System.err.println("[E R R O R] : No se pudo crear 'LISTEN SOCKET'");
System.exit(0);
}
Unreachable. Remove.
while(true){
System.out.println("Esperando algún cliente TCP en el puerto ["+portNumber+"]...");
myClient = myServer.accept();
if (myClient.isConnected()) { // if2
Once again this cannot possibly be false. You accepted the socket => it is connected. Don't write futile tests.
System.out.println("[D A T A] : El cliente ha sido aceptado IP-CLIENT\n"+""+ "IP Client address: "+myClient.getInetAddress());
DataOutputStream outClient = new DataOutputStream(myClient.getOutputStream());
DataInputStream inClient = new DataInputStream(myClient.getInputStream());
msj_ToServer = inClient.readLine();
System.out.println("Ha1 "+msj_ToServer);
try{
if(msj_ToServer.equalsIgnoreCase("D")) {
System.out.println("HO "+msj_ToServer);
outClient.writeBytes("ON");
Here you are writing bytes but no line terminator. The corresponding code in the client is using readLine()
, so it will block forever. Add a line terminator to this string.
outClient.flush();
Redundant. Remove. DataOutputStream
is not buffered, and neither is Socket.getOutputStream()
, so flushing either of them does nothing.
}catch(IOException e){
e.printStackTrace();
}
if(msj_ToServer == "B" || msj_ToServer == "b"){
System.out.println(msj_ToServer);
outClient.writeUTF("OFF");
Make up your mind. Are you writing bytes, or lines, or the special format used by writeUTF()
? The corresponding code in the client uses readLine()
. I suggest you standardize on writing lines for reading by readLine()
, or writeUTF()/readUTF()
. You cannot mix them.
outClient.flush();
See above. Remove.
if(msj_ToServer == "C" || msj_ToServer == "c"){
System.out.println(msj_ToServer);
outClient.writeUTF("xd");
See above.
outClient.flush();
See above.
MainActivity.clientSocket = new Socket("192.168.2.80", 30000);
try {
MainActivity.os = new PrintStream(MainActivity.clientSocket.getOutputStream());
MainActivity.is = new DataInputStream(MainActivity.clientSocket.getInputStream());
MainActivity.inputLine = new DataInputStream(new BufferedInputStream(System.in));
} // fin try
catch (IOException e){
System.err.println("algo anda al con los i/o ...");
} // fin catch
There is no reason to put these lines of code inside a try block. You're already inside one.
if (MainActivity.clientSocket.isConnected()) {
Yet again this test cannot possibly be false at this point. If the socket was constructed, it is connected.
It can however be null, due to your incorrectly structured exception handling. The block that follows this should be inside the prior enclosing try
block.
In general you should get rid of all the interior try/catch
blocks. Code that depends on the success of code in a prior try
block should be inside that try
block.
Upvotes: 2