Daten getrennt empfangen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

hi
ich kann mit meinem handy (samsung) die daten von meinem Handy an meinen pc schicken.
die daten, die ich verschicke, sind name, datenbankliste_1 und datenbankliste_2.
name und datenbankliste_1 funktionieren. datenbankliste_2 kommt zwar auch an, aber ich würde diese gern getrennt von datenbankliste_2
empfangen.
code Android:

Code: Alles auswählen

Socket socket = null;

try {

    SocketAddress sock_addresse = new InetSocketAddress(dstAddress, dstPort);
    socket = new Socket();
    int timeoutMs = 1000;
    socket.connect(sock_addresse, timeoutMs);

    SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy, HH:mm");
    String dateTime = sdf.format(new Date());

    ByteArrayOutputStream bAPS = new ByteArrayOutputStream(1024);
    byte[] server_Name = new byte[1024];
    int server_Information;

    List<String> list_Arbeit = new ArrayList<String>();
    List<String> list_Material = new ArrayList<String>();

    InputStream input_Message = socket.getInputStream();

    while ((server_Information = input_Message.read(server_Name)) != -1) {

        bAPS.write(server_Name, 0, server_Information);
        response += bAPS.toString("UTF-8");

        OutputStream out_Username = socket.getOutputStream();
        String userName = "Hans Hase";
        PrintStream print_userName = new PrintStream(out_Username);
        print_userName.print(userName);

        OutputStream out_datenbank_1 = socket.getOutputStream();
        String datenbank_1 = "DATENBANK_1";
        PrintStream print_datenbank_1 = new PrintStream(out_datenbank_1);
        print_datenbank_1.print(datenbank_1);

        OutputStream out_datenbank_2 = socket.getOutputStream();
        String datenbank_2 = "DATENBANK_2";
        PrintStream print_datenbank_2 = new PrintStream(out_datenbank_2);
        print_datenbank_2.print(datenbank_2);
    }

} catch (UnknownHostException e) {
    e.printStackTrace();
    failMessage = "IP-ADRESSE UNBEKANNT!";

} catch (IOException e) {
    e.printStackTrace();
    failMessage = "BAREBONE NICHT ERREICHBAR!";
}finally{
    if(socket != null){
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
            failMessage = "IO-Exception: " + e.toString();
        }
    }
}
code Python:

Code: Alles auswählen

streamSock.listen(25)
kontakt = 0

while True:
    client,addr = streamSock.accept()

    now = datetime.datetime.now()
    currentTime = now.strftime("%d.%m.%Y, %H:%M:%S")

    serverNameDatum = "Stream "+str(kontakt)+(":\n---> DMD-Server ("+currentTime+")\n")
    client.send(serverNameDatum)

    userName = client.recv(1024)
    print ("-------")
    print ("Stream "+str(kontakt)+(": ---> "+str(userName)+" ("+currentTime+")"))

    datenbank_1 = client.recv(2024)
    print datenbank_1

    #datenbank_2 = client.recv(3024)   #datenbank_2 kommt trotzdem an
    #print datenbank_2
    print ("-------")

    client.close()
    kontakt += 1

streamSock.close()
wenn ich datenbankliste_2 auskommentiere, werden trotzdem alle daten empfangen!?
die Ausgabe in Python sieht trotzdem so aus:

Code: Alles auswählen

-------
Stream 0: ---> Hans Hase (26.10.2016, 17:43:33)
DATENBANK_1DATENBANK_2
-------
DATENBANK_1 soll aber mit datenbank_2 = client.recv(3024) erhalten werden, den ich sogar auskommentieren kann.
Was mache ich denn falsch?
Zuletzt geändert von Anonymous am Mittwoch 26. Oktober 2016, 17:05, insgesamt 1-mal geändert.
Grund: Quelltext in Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@DMD-OL: TCP überträgt keine Pakete sondern nur einen Strom an Zeichen. Für die Interpretation bist Du selbst verantwortlich. Statt Dir irgendetwas selbst auszudenken, nimm doch ein Protokoll das für die Übetragung von Dateien gedacht ist, heutzutage üblich: HTTP.
BlackJack

@DMD-OL: Ein paar Anmerkungen zum Java-Code:

Auch in Java sollte man sich a) an die dortigen Namenskonventionen halten und b) sinnvolle, aussagekräftige, und passende Namen wählen. Also zum Beispiel nicht `bAPS` für etwas das `outputStream` genannt werden kann, oder `server_Information` für etwas das überhaupt keine Informationen über einen Server enthält sondern die Anzahl der gelesenen Bytes. So etwas wie `List` würde ich auch in Java nicht in den Namen schreiben.

Es macht keinen Sinn sich immer wieder neue `PrintStream`-Exemplare in der Schleife und dann auch noch für jede der drei Ausgaben zu erstellen.

Den `PrintStream` würde ich so erstellen, dass die Kodierung explizit mit angegeben wird. Und man sollte sicherstellen, das die Daten auch tatsächlich geschrieben und nicht irgendwo gepuffert werden.

Jetzt noch alle unbenutzen Variablen entfernt, lande ich ungefähr hier:
[codebox=java5 file=Unbenannt.java] try (Socket socket = new Socket()) {
try {
socket.connect(new InetSocketAddress(address, port), 1000);

ByteArrayOutputStream bufferStream = new ByteArrayOutputStream(BUFFER_SIZE);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
InputStream inputStream = socket.getInputStream();
PrintStream outputStream = new PrintStream(socket.getOutputStream(), true, "UTF-8");
while ((bytesRead = inputStream.read(buffer)) != -1) {
bufferStream.write(buffer, 0, bytesRead);
String response = bufferStream.toString("UTF-8");
// TODO: Do something with response.
outputStream.print("Hans HaseDATENBANK_1DATENBANK_2");
outputStream.flush();
}
} catch (UnknownHostException e) {
e.printStackTrace();
failMessage = "IP-ADRESSE UNBEKANNT!";
} catch (IOException e) {
e.printStackTrace();
failMessage = "BAREBONE NICHT ERREICHBAR!";
}
} catch (IOException e) {
e.printStackTrace();
failMessage = "IO-Exception: " + e;
}[/code]


Falls das jetzt nicht so aussieht wie Du Dir gedacht hast, insbesondere das `outputStream.print()`: Das macht das gleiche wie Dein Code. Es sendet alle drei Werte direkt hintereinander als Datenstrom per TCP.
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

deinen code habe ich schon verstanden, krass wie kurz das ist :(
danke für deine hilfe.
ich dachte man kann auch einzende string usw verschicken und die auch einzelnd empfangen.
mein endgültiges ziel ist es, den servernamen und datum, zeit an mein handy zu schicken und
zwei listen (die aus den beiden datenbanken auf meinem handy ausgelesen werden) an meinen pc zu schicken.
bin nur massiv zu blöd!
BlackJack

@DMD-OL: Dann brauchst Du ein Protokoll um die einzelnen Bestandteile der Nachrichten erkennen und trennen zu können. Wenn man selbst was bastelt wäre wahrscheinlich ein einfaches zeilenbasiertes Protokoll naheliegend. Also auf Java-Seite den Eingabestrom mit den entsprechenden Zwischenschritten zu einem `BufferedReader` machen von dem man dann Zeilen lesen kann und beim `PrintStream` entsprechend für Zeilenenden sorgen.

Das bedeutet natürlich das Zeilenenden nicht so einfach innerhalb der Daten vorkommen dürfen, und das man zum Beispiel bei Listen irgendwie kodieren muss welche Zeile zu welcher Liste gehört.

Alternativ nimmt man ein Protokoll und Serialisierungsformate die standardisiert sind. Beispielsweise HTTP für den Transport und JSON, XML, Messagepack, … für die (De)Serialisierung der Daten.
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

dann muß ich also erst einmal einen http server in python schreiben,
dann http clienten in android für mein handy.
dann die daten in python und android json verpacken und wegschicken?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@DMD-OL: zum Glück gibt es schon für alles fertige Pakete (z.B. SimpleHTTPServer für Python, com.google.api.client.http.javanet.NetHttpTransport für Android).
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

bezieht sich SimpleHTTPServer nicht auf webseiten, mit denen ich ja eigentlich nur auf webseiten?
ich will ja eine verbindung zwischen handy --> pc
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@DMD-OL: SimpleHTTPServer bezieht sich auf das Protokoll HTTP, mit dem man Daten austauschen kann.
Antworten