Java and Python socket communication

Asked

Viewed 41 times

1

I’m doing academic work where I’m developing an Android app that controls a robot simulation done in Python. I’m trying to communicate through a socket where pressing a key in the app sends the command of a certain letter so that the robot moves. I used as a basis some examples found here, but I believe I have not applied them correctly since the app (client) is not connecting with the application in python (server), I would like to know what I am doing wrong.

Edit: Updating the code with what was suggested in the comment, now by pressing a button with the event, the app crasha. The code of the Commsocket class and the Python application are up to date. I also added a log excerpt I collected from the phone at the time the application crashes. Improving the understanding of the situation, the test is done on a mobile phone and the application in python runs on a computer, both connected on the same network.

Python application code:

import socket
import rospy
from geometry_msgs.msg import Twist
import sys, select, os
if os.name == 'nt':
  import msvcrt
else:
  import tty, termios

if __name__=="__main__":

    HOST = '198.162.0.10'  # Endereco IP do Servidor
    PORT = 6789            # Porta que o Servidor esta
    queue = 5
    bufferSize = 256
    tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    orig = (HOST, PORT)
    tcp.bind(orig)
    tcp.listen(queue)

    try:
        print(msg)
        while(1):
#            key = getKey()
            con, cliente = tcp.accept()
            print ('Concetado por', cliente)
            key = con.recv(bufferSize)
            if key == 'w' :
                target_linear_vel = checkLinearLimitVelocity(target_linear_vel + LIN_VEL_STEP_SIZE)
                status = status + 1
                print(vels(target_linear_vel,target_angular_vel))
            elif key == 'x' :
                target_linear_vel = checkLinearLimitVelocity(target_linear_vel - LIN_VEL_STEP_SIZE)
                status = status + 1
                print(vels(target_linear_vel,target_angular_vel))
            elif key == 'a' :
                target_angular_vel = checkAngularLimitVelocity(target_angular_vel + ANG_VEL_STEP_SIZE)
                status = status + 1
                print(vels(target_linear_vel,target_angular_vel))
            elif key == 'd' :
                target_angular_vel = checkAngularLimitVelocity(target_angular_vel - ANG_VEL_STEP_SIZE)
                status = status + 1
                print(vels(target_linear_vel,target_angular_vel))
            elif key == ' ' or key == 's' :
                target_linear_vel   = 0.0
                control_linear_vel  = 0.0
                target_angular_vel  = 0.0
                control_angular_vel = 0.0
                print(vels(target_linear_vel, target_angular_vel))
            else:
                if (key == '\x03'):
                    break
            con.close()

Commsocket.java

import android.os.AsyncTask;
import android.os.Handler;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.SocketAddress;
import java.util.Arrays;

public class CommSocket extends AsyncTask<String, Integer, String>{
    private static final String hostname = "localhost";
    private static final String addr = "198.162.0.10";
    private static final int portaServidor = 6789;
    private IAsyncHandler mHandler;

    public CommSocket(IAsyncHandler mHandler) {
        this.mHandler = mHandler;
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            Socket socket = new Socket(addr, portaServidor);
            //SocketAddress socket = new InetSocketAddress(addr, portaServidor);

            //dados enviados para o servidor
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            //Estou usando Arrays.toString(), somente para ele pegar todas as strings que passar no
            //método.
            bw.write(Arrays.toString(params));
            bw.newLine();
            bw.flush();

            //dados recebidos pelo servidor
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String retorno =  "Dados cadastrados " + br.readLine(); //retornar ok
            socket.close();

            return retorno;
        }
        catch(IOException e) {
            return e.getMessage();
        }
    }

    @Override
    protected void onPostExecute(String result) {
        mHandler.postResult(result);
    }
}

Mainactivity.java

import android.os.Bundle;
import android.view.View;
import android.view.Menu;
import android.widget.TextView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;

import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

import com.example.tcc_wheelchair.CommSocket;

public class MainActivity extends AppCompatActivity implements IAsyncHandler{

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //CommSocket task = new CommSocket(MainActivity.this);

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery)
                .setDrawerLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }
    
    public void eventClickStop (View view)
    {
        TextView texto = findViewById(R.id.textViewteste);
        texto.setText("STOP");

        CommSocket task = new CommSocket(MainActivity.this);
        task.doInBackground("s");
    }

    public void eventClickUp (View view)
    {
        TextView texto = findViewById(R.id.textViewteste);
        texto.setText("UP ARROW");

        CommSocket task = new CommSocket(MainActivity.this);
        task.doInBackground("w");
    }

    public void eventClickDown (View view)
    {
        TextView texto = findViewById(R.id.textViewteste);
        texto.setText("DOWN ARROW");

        CommSocket task = new CommSocket(MainActivity.this);
        task.doInBackground("x");
    }

    public void eventClickRight (View view)
    {
        TextView texto = findViewById(R.id.textViewteste);
        texto.setText("RIGHT ARROW");

        CommSocket task = new CommSocket(MainActivity.this);
        task.doInBackground("d");
    }

    public void eventClickLeft (View view)
    {
        TextView texto = findViewById(R.id.textViewteste);
        texto.setText("LEFT ARROW");

        CommSocket task = new CommSocket(MainActivity.this);
        task.doInBackground("a");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }

    @Override
    public void postResult(String result) {
        //Neste método você pega o resultado da asynctask e aproveita de alguma forma
    }
}

interface IAsyncHandler {
    void postResult(String result);
}

Cell phone log:

--------- beginning of crash
06-03 23:07:52.266  9374  9374 E AndroidRuntime: FATAL EXCEPTION: main
06-03 23:07:52.266  9374  9374 E AndroidRuntime: Process: com.example.tcc_wheelchair, PID: 9374
06-03 23:07:52.266  9374  9374 E AndroidRuntime: java.lang.IllegalStateException: Could not execute method for android:onClick
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.view.View.performClick(View.java:6608)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.view.View.performClickInternal(View.java:6585)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.view.View.access$3100(View.java:785)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.view.View$PerformClick.run(View.java:25921)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.os.Handler.handleCallback(Handler.java:873)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:99)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:201)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:6864)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
06-03 23:07:52.266  9374  9374 E AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetException
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    ... 11 more
06-03 23:07:52.266  9374  9374 E AndroidRuntime: Caused by: android.os.NetworkOnMainThreadException
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:389)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.net.Socket.connect(Socket.java:621)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.net.Socket.connect(Socket.java:570)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.net.Socket.<init>(Socket.java:450)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at java.net.Socket.<init>(Socket.java:218)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at com.example.tcc_wheelchair.CommSocket.doInBackground(CommSocket.java:31)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    at com.example.tcc_wheelchair.MainActivity.eventClickUp(MainActivity.java:112)
06-03 23:07:52.266  9374  9374 E AndroidRuntime:    ... 13 more
06-03 23:07:52.357  1682  2970 W ActivityManager:   Force finishing activity com.example.tcc_wheelchair/.MainActivity
06-03 23:07:52.378  1682  1849 W BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.DROPBOX_ENTRY_ADDED flg=0x10 (has extras) } to com.google.android.gms/.stats.service.DropBoxEntryAddedReceiver
06-03 23:07:52.378  1682  1849 W BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.DROPBOX_ENTRY_ADDED flg=0x10 (has extras) } to com.google.android.gms/.chimera.GmsIntentOperationService$PersistentTrustedReceiver
06-03 23:07:52.382  1682  3467 D ActivityManager: report kill process: killerPid is:9374, killedPid is:9374
06-03 23:07:52.473  1682  2317 I WindowManager: WIN DEATH: Window{9e15302 u0 com.example.tcc_wheelchair/com.example.tcc_wheelchair.MainActivity}
06-03 23:07:52.474  1682  1776 I ActivityManager: Process com.example.tcc_wheelchair (pid 9374) has died: vis  TOP 
06-03 23:07:52.475  1682  1776 D ProcessManager: skip restart com.example.tcc_wheelchair because of low mem!
06-03 23:07:52.514  1682  1776 I Timeline: Timeline: App_transition_ready time:22000511
06-03 23:07:52.515  1682  1857 W ActivityManager: setHasOverlayUi called on unknown pid: 9374
06-03 23:07:52.522  1682  2448 I Timeline: Timeline: App_transition_ready time:22000519
06-03 23:07:52.537  1682  1929 V UiModeManager: switch night mode to 2
06-03 23:07:52.561  1682  1968 D ActivityManagerServiceInjector: Begin to report package foreground events...
06-03 23:07:52.564  1682  3467 I Timeline: Timeline: App_transition_ready time:22000560
06-03 23:07:52.576  1682  3467 I Timeline: Timeline: App_transition_ready time:22000572
06-03 23:07:52.621  1682  1929 V UiModeManager: switch night mode to 2
06-03 23:07:52.626  1682  3467 I Timeline: Timeline: App_transition_ready time:22000622
06-03 23:07:52.661  1682  1906 I Timeline: Timeline: App_transition_ready time:22000657
06-03 23:07:52.661  1682  1906 I Timeline: Timeline: App_transition_stopped time:22000657
06-03 23:07:52.668  1682  1857 I Timeline: Timeline: Activity_windows_visible id: ActivityRecord{c776715 u0 com.mi.android.globalFileexplorer/com.android.fileexplorer.activity.FileCategoryActivity t23447} time:22000665
06-03 23:07:52.713  1682  2969 I ActivityManager: Killing 7563:com.android.vending:download_service/u0a42 (adj 906): empty #17
06-03 23:07:52.740  1682  2436 D ConnectivityService: ConnectivityService NetworkRequestInfo binderDied(NetworkRequest [ TRACK_DEFAULT id=569, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED Unwanted:  Uid: 10042] ], android.os.BinderProxy@9406917)
06-03 23:07:52.741  1682  1946 D ConnectivityService: releasing NetworkRequest [ TRACK_DEFAULT id=569, [ Capabilities: INTERNET&NOT_RESTRICTED&TRUSTED Unwanted:  Uid: 10042] ] (release request)
06-03 23:07:52.741  1682  2970 D ProcessManager: skip restart com.android.vending:download_service because of low mem!
06-03 23:07:53.080  1682  2970 I ActivityManager: Killing 7770:com.google.android.gms.unstable/u0a30 (adj 906): empty #17
06-03 23:07:53.153  1682  2448 D ProcessManager: skip restart com.google.android.gms.unstable because of low mem!
06-03 23:07:55.004  1682  2448 W BaseMiuiPhoneWindowManager: keyCode:3 down:true eventTime:22002999 downTime:22002999 policyFlags:2b000002 flags:48 deviceId:-1 isScreenOn:true keyguardActive:false repeatCount:0
06-03 23:07:55.167  1682  2448 W BaseMiuiPhoneWindowManager: keyCode:3 down:false eventTime:22003163 downTime:22002999 policyFlags:2b000002 flags:48 deviceId:-1 isScreenOn:true keyguardActive:false repeatCount:0
06-03 23:07:55.253  1682  1921 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.miui.home/.launcher.Launcher (has extras)} from uid 1000

1 answer

0

Try this:

Socket socket = new Socket(addr, portaServidor);

instead:

 Socket socket = new Socket(hostname, portaServidor);

If they are on different machines (I’m guessing your Android app test is still on the emulator on the same machine the server is on) assign the IP of the host to addr in the application and in the HOST server python script. Try using local network IP instead of localhost (or 127.0.0.1) as these addresses are not accessible by other machines on the same network. Also, when testing the application on a mobile device remember to connect on the same server network.

  • Thanks for the reply, with these modifications when clicking on a button corresponding to the actions, the app crasha. The test is being done on a mobile device and the script running on the PC, both connected on the same network. Have any idea what it might be?

  • Update the question with the new code and with any error message you have access to to help better.

  • Hello Emerson, I edited the question and added a log. Thank you.

  • I never programmed for android but the Asynctask documentation ( https://developer.android.com/reference/android/os/AsyncTask ) says that you should not call doInBackground directly, so that the execution actually happens asynchronously, you should call the API execute method by passing the parameters. In your code it would be, for example, like this task.execute("w") instead of task.doInBackground("w"). Also note that this class is obsolete (@Deprecated) and that in future versions your code may stop working.

  • In this reply there is a brief explanation of why your code has failed: https://stackoverflow.com/a/22395546/4712790

Browser other questions tagged

You are not signed in. Login or sign up in order to post.