Android app side (Server) python (client) in Socket Programming - java

I am aiming to set up a server in android studio.I want my android application to receive external data using socket programming, so I wrote the codes I have shown below. I am having trouble learning the server IP of my Android application. That's why the connection is refused.
This server code in android studio:
package com.tefrikatli.fatura.myapplicationas;
import android.net.wifi.WifiManager;
import android.view.View;
import android.widget.EditText;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Handler;
public class MyserverOdom implements Runnable{
ServerSocket ss;
Socket mysocket;
DataInputStream dis;
String message;
EditText dt;
#Override
public void run() {
try {
dt.findViewById(R.id.textView22);
ss = new ServerSocket(6000);
//ss.accept();
while (true) {
mysocket = ss.accept();
dis = new DataInputStream(mysocket.getInputStream());
message = dis.readUTF();
dt.setText(message.toString());
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
this is anaother file :
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
public class MainActivity extends Activity {
ImageButton manuelgec;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manuelgec =(ImageButton)findViewById(R.id.manuelTemizlik);
manuelgec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent gec = new Intent(MainActivity.this,manuel_temizlik.class);
startActivity(gec);
Thread myThread = new Thread(new MyserverOdom());
myThread.start();
}
});
}
}
wlp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.43.220 netmask 255.255.255.0 broadcast 192.168.43.255
inet6 fe80::878d:6c3d:4ca4:4456 prefixlen 64 scopeid 0x20<link>
ether 54:8c:a0:32:32:f8 txqueuelen 1000 (Ethernet)
RX packets 647309 bytes 75238346 (75.2 MB)
RX errors 0 dropped 1086 overruns 0 frame 0
TX packets 681546 bytes 102623647 (102.6 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
mynet ip is: 192.168.43.220
I write ifconfig :
The client socket is :
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from math import degrees
import rospy
from nav_msgs.msg import Odometry
from nav_msgs.msg import OccupancyGrid
import cv2
import socket
global s
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.43.220', 6000)) #IP is the server IP
def odom_cb(msg):
seconds = rospy.get_time()
if (int(seconds) % 2 == 0):
try:
image = cv2.imread("/home/abdulsamet/catkin_ws/src/mobil/src/tubitak_v1.yaml.pgm")
den = image.shape
try:
xeksen = str(int(den[0]*11/20+(msg.pose.pose.position.x*19.2)))
yeksen = str((int(den[1]*11/20-msg.pose.pose.position.y*19.2)))
tam = xeksen + "," +yeksen
s.send(tam.encode())
except socket.error as msg:
print("de: ",msg)
except socket.error as msg:
print("Hata:",msg)
rospy.init_node('odom_to_path')
odom_sub = rospy.Subscriber('/odom', Odometry, odom_cb, queue_size=10)
rospy.spin()
This error is shown
Traceback (most recent call last):
File "/home/abdulsamet/catkin_ws/src/mobil/src/deneme.py", line 12, in
s.connect(('192.168.43.220', 6000)) #IP is the server IP
ConnectionRefusedError: [Errno 111] Connection refused
How to connect android app with my python script can someone help me what topics should i look at about this issue.

Related

Keeping a Client Socket alive between activities using a Service

I want to enter an IP address and port of a server using editText in Android studio. When a "connect" button is pressed, the entered information should be saved and be accessible to other activities. I have used the SharedPreferences method for saving the acquired data to be accessible across activities (Is this the best way to do so?). The successful creation of a client socket (handled in the service) is checked in the Connect activity (attached below) by means of (!client.isClosed()).
My problem is that whenever the activity reaches the check in the Connect.java activity, the isclosed is nullified. I assume that the client Socket is thus destroyed when it was created in the Service and called in the Connect.java activity.
Is there a way to create the Socket and keep it alive to be used by various other activities- I require the socket to be kept alive to receive/send messages to a server which will determine to which activity the App should transition. The method of creating and closing sockets in every activity will not work as it will be registered as a new user on the server side- firmware on a module I have no access to.
Any examples/documentation/help would be greatly appreciated.
I am very new to Android App development and Java so please be gentle if my questions are stupid :-)
Thank you very much for any assistance.
This is the service for handling the socket creation.
import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.StrictMode;
import android.util.Log;
import java.io.IOException;
import java.net.Socket;
public class SocketService extends IntentService
{
public Socket client;
public String ClientIP;
public Integer ClientPORT=0;
public SocketService()
{
super("SocketService");
}
#Override
protected void onHandleIntent(Intent Socketintent)
{
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
SharedPreferences savednotes= getSharedPreferences("Socket_NAME",
Context.MODE_MULTI_PROCESS);
ClientIP=savednotes.getString("IP_NAME",null); // Get the IP address
ClientPORT=savednotes.getInt("PORT_NAME",0); // Get the Port number
try
{
Log.d("IP", "Master IP address:" + ClientIP); // Debug to see
variables in Shared preferences
Log.d("PORT", "Port number: " + ClientPORT); // Debug to see
variables in Shared preferences
if ((ClientIP) != null)
{
if ((ClientPORT) != null)
{
client = new Socket(ClientIP, ClientPORT); // Create the Socket
}
}
} catch (IOException e)
{
e.printStackTrace();
try {
client.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
This is the Connect.java activity:
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.PrintWriter;
import java.net.Socket;
public class Connect extends AppCompatActivity
{
public Socket client;
private EditText etIP, etPORT;
private TextView status,IPs;
private Button buttonCON;
public int port=0;
public String IP;
SharedPreferences savednotes;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
setContentView(R.layout.activity_connect);
etIP = (EditText)findViewById(R.id.editTextIP);
etPORT = (EditText)findViewById(R.id.editText2);
buttonCON= (Button)findViewById(R.id.buttonCON);
status= (TextView)findViewById(R.id.textStatus);
IPs=(TextView)findViewById(R.id.textViewIP);
status.setText("Disconnected");
buttonCON.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
port = Integer.parseInt(etPORT.getText().toString());
IP= etIP.getText().toString();
IPs.setText(IP);
savednotes=
getApplicationContext().getSharedPreferences("Socket_NAME",
Context.MODE_MULTI_PROCESS);
SharedPreferences.Editor editor= savednotes.edit();
editor.putString("IP_NAME",IP);
editor.apply();
editor.putInt("PORT_NAME",port);
editor.apply();
Intent Socketintent= new Intent(Connect.this, SocketService.class);
startService(Socketintent);
int i = 0xFF00EE00;
status.setTextColor(i);
status.setText("Connected");
if (!client.isClosed())
{
Intent relay= new Intent(Connect.this, Relay.class);
startActivity(relay);
finish();
}
}
});
}
}
An IntentService is not a suitable solution for your objective. An IntentService is destroyed as soon as onHandleIntent() returns.
Most likely, you do not need any sort of Service here. A Service is for when you want to be doing work when you have no UI in the foreground, and that does not sound like your case here ("Keeping a Client Socket alive between activities"). An ordinary Java singleton would work, so long as you are very careful not to introduce memory leaks.
The method of creating and closing sockets in every activity will not work as it will be registered as a new user on the server side- firmware on a module I have no access to.
Bear in mind that your process does not live forever. Eventually, you will need to create a new socket.

How to start the client and connect to the server in AsyncTask?

I run on the computer through the command line server with port 6666. Tell me how can I connect to it by clicking on the button in the emulator? I appear in the broad gulls "Connecting ..." and then an error: W / System.err: java.net.ConnectException: Connection refused. At the same time when I run the server and the client just separate files, everything works, it does not matter the command line or in android studio. What am I doing wrong?
Here is MainActivity:
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import android.app.Activity;
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.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Button but;
MyTask mt;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but = (Button) findViewById(R.id.btnOk);
but.setOnClickListener(this);
}
public void onClick(View v) {
mt = new MyTask();
mt.execute();
}
class MyTask extends AsyncTask<Void, Void, Void> {
int port = 6666;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
int serverPort = 6666;
String address = "127.0.0.1";
try {
InetAddress ipAddress = InetAddress.getByName(address);
System.out.println("Connecting...");
Socket socket = new Socket(ipAddress, serverPort);
System.out.println("Connected");
} catch (Exception x) {
x.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
}
I get the following error:
java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:334)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:196)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356)
at java.net.Socket.connect(Socket.java:605)
at java.net.Socket.connect(Socket.java:554)
at java.net.Socket.<init>(Socket.java:431)
at java.net.Socket.<init>(Socket.java:241)
at com.tenday.myapplication.MainActivity$MyTask.doInBackground(MainActivity.java:56)
at com.tenday.myapplication.MainActivity$MyTask.doInBackground(MainActivity.java:41)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
If you are using the emulator probably the IP address you are using is wrong you should use 10.0.0.2. see the android docs
change the IP address you are connecting to
String address = "127.0.0.1";
use the IP address of the machine that runs the server, as 127.0.0.1 will point to the mobile not the computer that hosts the emulator.
you should use something like
String address = "192.168.100.10";
or whatever IP address the computer have

Android: Connecting to the server

I'm running a simple local server and I just want to watch in terminal if my app is succesfully connected to the server.
Installation and build is succesful, but nothing (by nothing I mean no connection, of course there aren't any data) happens. The server is surely running, the port is set to 8080, my phone is connected to the internet (tried both wifi and data) I'm working with Android Studio, and I added these permissions to my manifest in:
AndroidManifest.xml
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
...
ActivityMain.java
package tlacitko.button;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendMessage(View view) {
new Thread(new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
try{
URL url = new URL("http://147.32.186.51:8080");
InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new
InputStreamReader(is));
String s = "";
}catch(MalformedURLException ex){
}catch(IOException e){
}
}
});
}
}).start();
}
}

Can't receive packets on android app

I can't receive any packets on my app. I have a computer running from console-php this script:
$broadcast_string='http://hellokitty/shownumber.html';
$port=2328;
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1);
while(true){
socket_sendto($sock, $broadcast_string, strlen($broadcast_string), 0, '255.255.255.255', $port);
sleep(1);
echo "Broadcasting ...\n";
}
on the other hand I got this code running on my phonegap app on the MainActivity.java file:
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.content.Context;
import org.apache.cordova.*;
import java.io.*;
import java.net.*;
import java.util.*;
import android.content.BroadcastReceiver;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.content.Context;
import android.app.DialogFragment;
import android.app.AlertDialog;
import android.view.Menu;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.provider.Settings;
import android.view.WindowManager;
import android.util.Log;
import android.content.res.AssetManager;
public class MainActivity extends CordovaActivity
{
public static String URL = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
DatagramSocket socket;
//Wakelock------------------------------------------------------------------------------------------------------------------
WakeLock mWakeLock = null,mPartialWakeLock = null;
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
// lock used to keep the processor awake.
mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);
mPartialWakeLock.acquire();
final WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock lock = wifi.createMulticastLock("UDP");
lock.acquire();
//--------------------------------------------------------------------------------------------------------------------------
try {
//Keep a socket open to listen to all the UDP trafic that is destined for this port
//socket = new DatagramSocket(2328, InetAddress.getByName("0.0.0.0"));
socket = new DatagramSocket(2328);
socket.setBroadcast(true);
URL = null;
while (URL == null) {
System.out.println(getClass().getName() + ">>>Ready to receive broadcast packets!");
//Receive a packet
byte[] recvBuf = new byte[12000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
//socket.setSoTimeout(10000);
socket.receive(packet);
//Packet received
System.out.println(getClass().getName() + ">>>Discovery packet received from: " + packet.getAddress().getHostAddress());
System.out.println(getClass().getName() + ">>>Packet received; data: " + new String(packet.getData()));
String message = new String(packet.getData()).trim();
URL=message;
break;
}
} catch (IOException ex) {
//Nothing
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
while(URL == null){
continue;
}
Log.d("net_discover",URL);
super.loadUrl(URL);
}
}
I've tested the network sniffing packets and traffic it's ok.
I've added the wakelock section since I've read that android blocks broadcast packets, but I'm still not getting anything on my device.
I'm working on a Motorola running Android 4.4.4
On the adb logcat, app is stuck on the msg "Ready to receive.." and that's all I get.
Any suggestions?
UPDATE:
I added code to my app to send packet before starting receiving and for my surprise it does receive it. So I started sending packets and sniffing the network from my computer and I don't see any. So doing some more research I found that the app is working on the lo interface (loopback, 127.0.0.1).
So my question now is, how do I make the app receive packets from wifi interface?

Problem with MulticastSocket on Java-Android

I'm starting to code with MulticastSocket, trying to make a simple app with a client and a server to send messages.
The code I have for the server:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
public class Servidor {
private static MulticastSocket ms;
public static void main(String[] args) throws IOException{
InetAddress sessAddr = InetAddress.getByName("224.2.76.24");
try{
sessAddr = InetAddress.getByName("224.2.76.24");
ms = new MulticastSocket(5500);
ms.joinGroup(sessAddr);
while (true)
{
byte[] mensaje = new byte[1024];
mensaje = "aa".getBytes();
DatagramPacket dp = new DatagramPacket(mensaje, mensaje.length,sessAddr,5500);
ms.send(dp);
}
}
catch (SocketException se) {
System.err.println(se);
}
ms.leaveGroup(sessAddr);
}
}
And this on the client:
package com.example;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
public class ClienteMultiCast extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView Mensaje;
Mensaje =(TextView)findViewById(R.id.Mensaje);
InetAddress ia = null;
byte[] buffer = new byte[65535];
MulticastSocket ms = null;
int port = 5500;
try {
ia = InetAddress.getByName("224.2.76.24");
DatagramPacket dp = new DatagramPacket(buffer, buffer.length,ia,port);
ms = new MulticastSocket(port);
ms.joinGroup(ia);
while (true) {
ms.receive(dp);
String s = new String(dp.getData(),0,dp.getLength());
Mensaje.setText(s);
}
} catch (UnknownHostException e) {Mensaje.setText(e.getMessage());} catch (IOException e) {Mensaje.setText(e.getMessage()); }
try {
ms.leaveGroup(ia);
} catch (IOException e) {
Mensaje.setText(e.getMessage());
}
}
}
The problem is that when I start both, nothing happens. The client doesn't get any message.
Any idea what's wrong?
Diego,
By default, the Android WiFi stack filters out multicast packets. Take a look at http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html.
You need something along the lines of:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* Turn off multicast filter */
MulticastLock mcastLock = new MulticastLock();
mcastLock.acquire();
/* Process Multicast Packets */
}
It appears that Multicast support in Android is not as solid as some of use might hope. See http://codeisland.org/2012/udp-multicast-on-android/
Ie whether it actually works out or may be device dependent. It is not working on my Nexus5.
https://code.google.com/p/android/issues/detail?id=51195

Categories

Resources