# Android to Pi | Websocket Problem



## Kiwi_gamer01 (20. Mai 2020)

Ich habe eine Android App welche einen command meinen Pi sendet
btnUp sendet up
btnDown sendet down
btnstop sendet stop

Code am Handy:


```
package com.example.wifi_rasp;

import android.os.AsyncTask;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.util.Log;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class MainActivity extends AppCompatActivity {
//UI Element
Button btnUp;
Button btnDown;
Button btnStop;
EditText txtAddress;
Socket myAppSocket = null;
public static String wifiModuleIp = "";
public static int wifiModulePort = 0;
public static String CMD = "0";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btnUp = (Button) findViewById(R.id.btnUp);
btnDown = (Button) findViewById(R.id.btnDown);
btnStop = (Button) findViewById(R.id.btnStop);

txtAddress = (EditText) findViewById(R.id.ipAddress);

btnUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getIPandPort();
CMD = "up";
Socket_AsyncTask cmd_increase_servo = new Socket_AsyncTask();
cmd_increase_servo.execute();
}
});
btnDown.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getIPandPort();
CMD = "down";
Socket_AsyncTask cmd_increase_servo = new Socket_AsyncTask();
cmd_increase_servo.execute();
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getIPandPort();
CMD = "stop";
Socket_AsyncTask cmd_increase_servo = new Socket_AsyncTask();
cmd_increase_servo.execute();
}
});

}
public void getIPandPort()
{
String iPandPort = txtAddress.getText().toString();
Log.d("MYTEST","IP String: "+ iPandPort);
String temp[]= iPandPort.split(":");
wifiModuleIp = temp[0];
wifiModulePort = Integer.valueOf(temp[1]);
Log.d("MY TEST","IP:" +wifiModuleIp);
Log.d("MY TEST","PORT:"+wifiModulePort);
}
public class Socket_AsyncTask extends AsyncTask<Void,Void,Void>
{
Socket socket;

@Override
protected Void doInBackground(Void... params){
try{
InetAddress inetAddress = InetAddress.getByName(MainActivity.wifiModuleIp);
socket = new java.net.Socket(inetAddress,MainActivity.wifiModulePort);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeBytes(CMD);
dataOutputStream.close();
socket.close();
}catch (UnknownHostException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}
return null;
}
}
}
```
Bei den Pi kommt leider nicht "up" an sondern:



```
Waiting for connection
...connected from : ('192.168.1.XX', 52932)
u
p
als einzelne Buchstaben und nicht als ein string
```

Was muss ich machen das wenn up gesendet wird auch up ankommt und nicht u; p.






Code auf dem Pi: (müste unwichtig sein)

```
from socket import *
from time import ctime
#import Rollo
import RPi.GPIO as GPIO
import sys

#Rollo.setup()          #if necessary

ctrCmd = ['Up','Down','Stop']

HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)

tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

while True:
print 'Waiting for connection'
tcpCliSock,addr = tcpSerSock.accept()
print '...connected from :', addr
try:
while True:
data = ''
data = tcpCliSock.recv(BUFSIZE)
print data
if not data:
break
if data == ctrCmd[0]:
#                                Rollo.Up()
print ('Up', sys.argv)
if data == ctrCmd[1]:
#                                Rollo.Down()
print ('Down', sys.argv)
if data == ctrCmd[2]:
#                               Rollo.Stop()
print ('Stop', sys.argv)
except KeyboardInterrupt:
#                Rollo.close()          #if necessary
GPIO.cleanup()
tcpSerSock.close();
```


----------



## kneitzel (20. Mai 2020)

Also Du scheinst schon genau dieses "up" zu senden und das kommt auch genau so an. Nur scheinbar liest Deine Schleife die Daten Byte für Byte ein.

Wenn ich Daten per tcp/ip versendet habe, dann habe ich immer ein klares Protokoll implementiert. Da sehe ich mehrere Möglichkeiten:
- Dein Client sendet nur einen Befehl, d.h. du lädst einfach in der Schleife so lange Daten, bis die Verbindung geschlossen wird. Dann wertest Du die empfangenen Zeichen erst aus.
- Du definierst ein Trennzeichen. Dann kann eine Verbindung auch mehrere Dinge schicken. Ein Zeilenumbruch kann hier z.B. benutzt werden. Aber prinzipiell ist es so wie oben auch: Deine Schleife liest Zeichen bis das Trennzeichen empfangen wurde. Dann wird der Puffer bis einschließlich Trennzeichen ausgewertet und der Rest bleibt aber im Puffer.
Dies muss dann meist nicht selbst geschrieben werden sondern es gibt meist eine Implementation, die Text Zeilenweise liest. Die kann man dann z.B. nutzen...

Wichtig ist halt, dass Daten in dem Stream beliebig zerstückelt und wieder zusammen gesetzt werden kann. Also wenn Du mehrere Nachrichten schickst, dann ist nur sicher gestellt, dass du alles der Reihe nach empfängst. Aber das kann in Teilschritten erfolgen. Wenn Du also die Zeilen 
Zeile 1
Zeile 2
versendest, dann kann ankommen als erstes:
Zei
Dann:
le 1
Z
Dann der Rest
eile2

Nur um mal ein Beispiel aufzuzeigen.

Generell finde ich das aber interessant. Das Verhalten ist untypisch. Dieses Aufteilen erfolgt ja, weil die Daten in TCP/IP Paketen mit einer gewissen maximalen Länge versendet werden. Und die 2 Byte (writeBytes schickt pro Zeichen nur das untere Byte - also sehr beschränkt was den Zeichensatz angeht!) passen ja in ein TCP/IP Paket.... Und auf Empfangsseite hätte ich dann eigentlich erwartet, dass dies auch entsprechend ausgelesen wird.

Dann noch der Hinweis: Bitte keine Doppel-Posts. Du hast doch vor wenigen Stunden das erst gepostet! Bleib in dem Thread, den Du erstellt hast und erstelle keinen zweiten!


----------



## Kiwi_gamer01 (20. Mai 2020)

```
Waiting for connection
...connected from : ('192.168.1.55', 46967)
u
p

Waiting for connection
...connected from : ('192.168.1.55', 46968)
s
top

Waiting for connection
...connected from : ('192.168.1.55', 46969)
d
own
```
kannst du mir das erkären?


----------



## kneitzel (20. Mai 2020)

Aus welchem Grund auch immer liest er immer erst nur ein Zeichen statt gleich allen. Wie das prinzipiell aussieht habe ich ja bereits versucht zu erläutern ebenso die Lösungsideen.

Python nutze ich nicht, daher kann ich da aber nicht wirklich Codebeispiele aufbauen.


----------

