TheMeaningfulEngineer
TheMeaningfulEngineer

Reputation: 16359

Receiving hexadecimal values from socket instead of strings on SocketServer

I opened a socket between an Android app and a python server. The combination is that the Server listens, and android connects to the Server.

Here is the server code. The problematic part takes place in the definition of handle :

import SocketServer
from time import sleep
import sys

HOST = '192.168.56.1'
PORT = 2000

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    def handle(self):
    try:
        while(1):
            sleep(0.03)
            data = self.rfile.readline().strip()

            print data
    except KeyboardInterrupt:
        sys.exit(0)

class SimpleServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    allow_reuse_address = True

    def __init__(self, server_address, RequestHandlerClass):
        SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)


server = SimpleServer((HOST, PORT), SingleTCPHandler)
try:
    server.serve_forever()
except KeyboardInterrupt:
    sys.exit(0)

The connection is established normally, and the Android app sends the following data to the socket:

'0:0'

But the data is received on the Server as:

'\x000\x00:\x000\x00'

The variable that receives the data is:

data = self.rfile.readline().strip()

and printing gives the regular format:

In [2]: print data
0:0

I didn't manage to step into the print function with pdb to see what it does. I'm looking for a way to convert the '\x000\x00:\x000\x00' to '0:0'.

Please advise on a way to convert the variable. You are welcome to comment/criticize the whole implementation. This is my first project in dealing with sockets so i don't know the pitfalls.

Update

This was the original Android code:

String podaci = "0:0";
public void Socketic() throws IOException {

    Socket mojSocket = new Socket(urlServer, port);

    DataOutputStream izlazdata = new DataOutputStream(
            mojSocket.getOutputStream());
    while (podaci != "end") {
        try {
            Thread.sleep(60);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }

        izlazdata.writeChars(podaci);
        izlazdata.flush();
    }
    izlazdata.close();
    mojSocket.close();
};

And the problem was, as you suspected in:

izlazdata.writeChars(podaci);

writeChars uses the method writeChar. The API documentation for writeChar states:

Writes a char to the underlying output stream as a 2-byte value, high byte first...

The two bytes represent the 16bits which UTF-16 uses for encoding.

When we changed it to everything started working:

izlazdata.writeBytes(podaci);

Update

Based on the answers given, here is how the unwanted string is to be interpreted in terms of characters.

enter image description here

This solves my concrete problem, however, if someone would give a more generic solution to what happend here so that a larger lesson can be learned. If not, i will accept Esailijas answer in a few days.

Upvotes: 1

Views: 676

Answers (1)

Esailija
Esailija

Reputation: 140236

You need to show the code happening Android but it strongly seems like it's sending data in UTF-16BE. You should specify the encoding on the Android end. The characters are not hexadecimal literally, but because the NUL character is unprintable, python shows \x00 instead.

Another option is to decode it:

self.rfile.readline().decode("utf_16_be").strip()

note that the result of this is an unicode string.

Upvotes: 3

Related Questions