1

I'm trying to get two systems to communicate, I want my C# application to talk trash with a TCP server written in Python.

First I thought of serialization, and got a good look at google's protobuf. But don't you only need serialization if you have complex types and datastructures. I don't. I only want to send a enum (The default underlying type of the enumeration elements is int (Signed 32-bit integer).).

But the enum defined is rather large (C#):

[Flags]
public enum RobotCommands
{
    reset = 0x0,        // 0
    turncenter = 0x1,   // 1
    turnright = 0x2,    // 2
    turnleft = 0x4,     // 4
    standstill = 0x8,   // 8
    moveforward = 0x10, // 16
    movebackward = 0x20,// 32
    utility1on = 0x40,  // 64
    utility1off = 0x80, // 128
    utility2on = 0x100, // 256
    utility2off = 0x200 // 512
}

So really, do I need serialization? What's the easiest way by Python to be able to read my enums that I send it?

I've tried just sending it as string, hoping to convert them back, but they seem to be string:

#!/usr/bin/env python

import socket

TCP_IP = '192.168.1.66'
TCP_PORT = 30000
BUFFER_SIZE = 20  # Normally 1024, but we want fast response

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

conn, addr = s.accept()

print 'Connection address:', addr

while True:
    data = conn.recv(BUFFER_SIZE).encode("hex")
    print "received data:", data    

    if( (data & 0x8) == 0x8 ):
        print("STANDSTILL");

    if not data: break

    conn.send(data)

conn.close()
radbyx
  • 9,352
  • 21
  • 84
  • 127
Jason94
  • 13,320
  • 37
  • 106
  • 184
  • You are confusing python literal int notation in hex, and encoding a byte to hexadecimal presentation. *They are not the same thing*. I already told you in a [previous question](http://stackoverflow.com/q/11791161/) about the struct module. – Martijn Pieters Aug 05 '12 at 11:34

2 Answers2

1

Just passing the enum as string is OK. You can get them back to integer using int method.

cmd = int(data);

If you want hex version, using:

cmd = hex(int(data))


int(x[, base]) -> integer                                                                           

Convert a string or number to an integer, if possible.  A floating point
argument will be truncated towards zero (this does not include a string
representation of a floating point number!)  When converting a string, use
the optional base.  It is an error to supply a base when converting a
non-string.  If base is zero, the proper base is guessed based on the
string content.  If the argument is outside the integer range a
long object will be returned instead.


hex(number) -> string                                                                               

Return the hexadecimal representation of an integer or long integer.
xiaowl
  • 5,177
  • 3
  • 27
  • 28
  • Why would you want the hex version? That suggests treating it as a *string*, when one would typically just want the *bytes*. – Marc Gravell Aug 05 '12 at 11:50
0

In that scenario, I would just send a 4-byte network-byte-order chunk of the underlying value, i.e.

RobotCommands cmd = ...
int i = (int) cmd;

You can get the bytes for that in many ways; maybe a BinaryWriter on the NetworkStream, maybe BitConverter, or maybe just shift-operators. Then read the same 4 bytes in your other language, and treat them as an integer. You should be able to cast the integer to an ipenum in any language, or alternatively: just use bitwise-operators.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900