Phablo81
Posts: 2
Joined: Sat May 18, 2019 4:43 pm

Can't send message from Python Server to Java Client

Sat May 18, 2019 4:55 pm

I created a Server (python) on Raspberry and then I created a Client (Java) with Android Studio.
Basically through an app I can turn on an led connect on the Raspberry and this run very well. But now I want to sent a message from the server to client in order to understand if the LED has been turnedon or not.

Please somebody could suggest me how to change the code (below) in order to send the message from Server (Python) to Client (Java)?

Below the Code for the Server and Client:

Code: Select all

*****************Server (Python)********************************

import socket
import RPi.GPIO as GPIO
from time import sleep

running=True
pp=True
listensocket=socket.socket()
Port=5000
maxCOnnection=999
IP="192.168.1.7"
message=''


def inAscolto():
    global running
    global clientsocket
    global messaggio
    print("Sertver started at  " + IP + " on port " + str(Port))
    listensocket.bind(('',Port))
    listensocket.listen(maxCOnnection)
    while running:
        print("Waiting for input..")
        (clientsocket, address) = listensocket.accept()
        pp=True
        print("New connection made!")
        elabora()
        
def elabora():
    global pp
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(17,GPIO.OUT)
    message=clientsocket.recv(1024).decode()
    print(message)
    #data = clientsocket.recv(1024)
    #clientsocket.sendall(data)
    print("Message sent")
    if message == "AA":
        GPIO.output(17,GPIO.HIGH)
        sleep(5)
        GPIO.output(17,GPIO.LOW)
        message=""
        pp=False
        clientsocket.close()
    else:
        print("Niente")
        clientsocket.close()
        #running=False


if __name__ == '__main__' :
    inAscolto()

*****************Client(Java)********************************

public class MainActivity extends AppCompatActivity {
   Button accendi;
   Button spegni;
   TextView testo;
   String prova2;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       accendi=(Button)findViewById(R.id.btnAccendi);
       spegni=(Button)findViewById(R.id.btnSpegni);
       testo=(TextView)findViewById(R.id.txt1);

       accendi.setOnClickListener(new View.OnClickListener(){
           @Override
           public void onClick(View v){
               send sendcode=new send();
               testo.setText(prova2);
               sendcode.execute();
           }
       });
   }

   class send extends AsyncTask<Void,Void,Void>{
       Socket s;
       PrintWriter pw;


       @Override
       protected Void doInBackground(Void... params) {
           try{
               s=new Socket("192.168.1.7",5000);
               pw=new PrintWriter(s.getOutputStream());
               InputStream is = s.getInputStream();
               InputStreamReader isr = new InputStreamReader(is);
               BufferedReader br = new BufferedReader(isr);
               prova2 = br.readLine();
               pw.write("AA");
               pw.flush();
               pw.close();

           }catch (UnknownHostException e){
               System.out.println("Fail_1");
               e.printStackTrace();
           }
           catch (IOException e){
               System.out.println("Fail_2");
               e.printStackTrace();
           }
           return null;
       }
   }

Heater
Posts: 12670
Joined: Tue Jul 17, 2012 3:02 pm

Re: Can't send message from Python Server to Java Client

Sun May 19, 2019 8:09 am

I think you should do a little background reading how how TCP/IP server and clients interact.

Typically the server:

1) Creates a socket.
2) Listens for connections from clients
3) When connected the client and server can both send an receive data
4) When done, close the client socket.

Note that many clients can connect, the server is always listening and creates a new socket for each new client connection.

Meanwhile the client:

1) Creates a socket
2) Connects to the server
3) When connected the client and server can both send an receive data
4) When done, close the client socket.

There is only one socket on the client side.

An important point here is that a server cannot send data to a client whenever it likes. The client has to open a connection first.

Often one might open a connection from client to server and keep it open, exchanging data over a long period of time.

Or, one might have the client open a connection, send a request, get the response back, close the connection. All in a short transaction.

Which way you do it is up to you. I guess if you want the server to be able to send to clients at any time the clients had better connect and keep the connection open permanently.

Have a read of this: https://realpython.com/python-sockets/#background

Phablo81
Posts: 2
Joined: Sat May 18, 2019 4:43 pm

Re: Can't send message from Python Server to Java Client

Sun May 19, 2019 8:21 am

Thanks heater for your answer.
I a have an question when the serve send a message to the client: should this message a simple string or it must be codified?

Heater
Posts: 12670
Joined: Tue Jul 17, 2012 3:02 pm

Re: Can't send message from Python Server to Java Client

Sun May 19, 2019 11:22 am

Phablo81,
...should this message a simple string or it must be codified?
There is another very important thing that you should be aware of:

When you have a TCP/IP connection between client and server there are no "messages". What you have is a means to exchange bytes between client and server. A continuous stream of bytes.

That potentially infinite stream of bytes you are sending will be chopped up into smaller chunks for transmission, these are "packets". You have no control over how your OS or any routers the link will chop and join packets as they travel through the network.

What this means is that a recv() at the receiver will not necessarily return the same batch of bytes you sent in a send(). Perhaps what you gave to send() was too big to put in a packet, it will be chopped up into many packets. Perhaps it was quite small, then it will be merged with data from other sends you have made recently to fill a packet.

What all that means is that you have to impose your own "message" format on that stream of data. Could be as simple as sending string with line terminations (carriage return/line feed or both). The the receiver gets the data from recv() and scans it looking for a line ending. Then it know a new "message" line has started. Then it has to read the character from that line and check for the next line termination, then it knows the line has ended.

If you don't synchronize things like this you will have a mess. There are many ways to do it of varying complexity.

Having said all that, why use low level TCP/IP sockets and have to do all that? Why not use a ready made protocol for exchanging messages like MQTT?

With MQTT you run a ready made server that is a separate program than either your sender or receiver. Commonly called a "broke". Then your machines connect to the MQTT server as clients and send it messages. MQTT will relay those messages to your other machines. MQTT tales care of all that messy message framing problem.

When a machine wants to send a message it simply does this:

Code: Select all

client.publish("topic/test", "Hello world!");
Anyone wanting to receive that message will do this:

Code: Select all

def on_message(client, userdata, msg):
  if msg.payload.decode() == "Hello world!":
    print("Yes!")
Simple!

Have a look at this: https://www.ev3dev.org/docs/tutorials/s ... with-mqtt/

MQTT is used my a lot or people doing what you want to do.

Return to “Python”