[változott] Python, TCP, 4 byte küldése, endianness, C#

új infó a topicnyitó végén

Ajaj, próbáltam a címet erősen zanzásítani... :)

Sziasztok!

Amin ügyködök, a következő.
Van ez a szoftver, telefonra, illetve egy TCP szerver váza C#-ban, az alábbi oldalon:
http://philip.daubmeier.de/sensoremitter/

Az Win-es telefonról küldi TCP-n a szenzoradatokat a pc-re.

Van ez a szoftver:
https://github.com/ianovir/HIMUServer

Ami úgy tűnik, némi módosítás után alkalmas lehetne arra, hogy fogadjam az adatokat a Windows-os telefonról.

Azzal küzdök, hogy a C# forrás szerint küldeni kellene a telefonon futó "kliens"-nek egy MagicNumbert TCP-n, amit át kellene alakítani Big Endianná, hogy a hálózaton biztos rendben érkezzen meg.
A kliens forrása zárt, az csak a Win Store-ból tölthető le.

Namost Pythonban (3-ast "használok") a

socket.htons

csak 2 byteot cserél, meg a pack is, nem pedig négyet...

...és itt a biológus agyam elvesztette a fonalat, segítséget kell kérnem... :)

Értem én, hogy lesznek más bajok is majd, de itt leragadtam.

A socket nyitva, beszélek is a telefonhoz, de az szól, hogy valami a másik oldalon nem kóser (nézzem meg, hogy tűzfal nem blokkol-e, esetleg szó nélkül kilép (itt gondolom valamilyen nem kezelt kivétel történik)).

A python szerver releváns részei itt lejjeb. A gányolás látszik... :)


import socket
import math
from struct import *
import sys

timeout = 10  #timeout in seconds
bufferSize = 1024 #bytes
MagicNumber = 0x42fea723 # Big Endian int32 http://www.scadacore.com/field-tools/programming-calculators/online-hex-converter/
#MagicNumber = 0x23a7fe42 # Little Endian int32
#packSeparator="#"
packSeparator=""
go=True;
.
.
.

def executeTCP(port):
	'''
	Performs data acquisition via TCP protocol
	'''
	sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	sock.settimeout(timeout)
	serverAddress = ('', port)
	sock.bind(serverAddress)
	sock.listen(1)
	print ('waiting for connection')
	[connection, clientAddress] = sock.accept()
	print ('Sending magic number')
	print ("MagicNumber type: ", type(MagicNumber).__name__)
	print ("MagicNumber size: ",  sys.getsizeof(MagicNumber))
	#magicnum = pack('i', bytearray.fromhex(hex_string))
	magicnum_2 = pack("!I", MagicNumber)
	print ("magicnum_2: ", magicnum_2)
	print ("magicnum_2 type: ", type(magicnum_2).__name__)
	sock.send(magicnum_2)			# http://stackoverflow.com/questions/8904092/how-can-i-send-anything-other-than-strings-through-python-sock-send
	connection.setblocking(1)
	print ('connection from ' + str(clientAddress))
	while go:
		data = connection.recv(bufferSize)	
		if not data: break
		printSensorsData(data.decode("utf-8"))
	connection.close()		

.
.
.

szerk:
Úgy tűnik, wireshark-kal belehallgatva a beszélgetésbe, hogy a python szerver hallgat, a 2 eszköz között pontosan 0 byte információ közlekedik. Mármint persze a syn-ack pároson kívül. :)
Magyarul nem küldi el a stringet a szerver.
Erős a gyanúm, de itt tényleg kezdek kidőlni, hogy nem jó helyen próbálom küldeni az adatokat.
Olvasgatok, de kezdek elveszni.
A Python doksik szerint ha (mondjuk TCP) szervert szeretnék, a socket.bind, .listen, .accept kell.
Ha kliens akarok lenni, az is megvan. (mármint legalábbis a doksikban :))

De azt nem értem, hogy ha én szerverként szeretnék létezni, de el szeretnék küldeni egy stringet 4 byte-ot a kliensnek (mondjuk a már felépített kapcsolaton keresztül), akkor most szerver vagyok, kliens, vagy rohadt sokat kellene még olvasnom...? :)

Komolyan: ha valaki segítene ebben az ügyben, megköszönném! :)

Hozzászólások

Bitbanging helyett javasolnám protobuf vagy hasonló használatát.

--

socket.htonl(x)
Convert 32-bit positive integers from host to network byte order. On machines where the host byte order is the same as network byte order, this is a no-op; otherwise, it performs a 4-byte swap operation.

Köszönöm!
Ez a része rendben.

...akkor most már csak ezt nem értem...:


>>> magicnum = 0x42fea723
>>> import sys
>>> sys.getsizeof(magicnum)
18
>>> import socket
>>> hex(socket.htonl(magicnum))
'0x23a7fe42'
>>> sys.getsizeof(hex(socket.htonl(magicnum)))
35

Hogy lesz egy int-ből 18 bájt, majd a htonl után 35?
Arra számítottam volna, hogy 4 bájt előtte, utána is.
Úgy tűnik, nem, egyébként meg a htonl kimenete rendben levőnek tűnik.

szerk:
Oké, dereng:
http://stackoverflow.com/questions/14329794/get-size-of-integer-in-pyth…

<-------
You can't grep on dead trees.

A fenti kód nekem sem nagyon akarat elindulni, kicseréltem ezt:

sock.send(magicnum_2)
connection.setblocking(1)
print ('connection from ' + str(clientAddress))

erre:

print ('connection from ' + str(clientAddress))
connection.send(magicnum_2)
connection.setblocking(1)

és már ment is.
A print helyzete izlés kérdése, a lényeg a sock.send() helyett a connection.send().
Amit netcat-al (ez volt kéznél) beleküldtem, az megjelent a "server" oldalon.

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
...
[connection, clientAddress] = sock.accept()

A 'sock' változó által kijelölt socketen csak a "hallgatózás" folyik, és ha ezen egy kliens jelentkezik kapcsolatfelvételre, akkor egy új "adatkapcsolati" socket, itt a "connection" jön létre és ezen kell forgalmazni.
Ez így van, akkor is ha C-ben vagy PHP-ban kell a socketeket kezelni.

--
eutlantis

Feltétlenül ragaszkodsz a python-hoz? Sajnálatos módon nekem az a brainfuck nyelv variánsok egyike :)
Egy félig jogosan széthurrogott PHP esetleg? :)

// Happy debugging, suckers
#define true (rand() > 10)

Köszönöm mindenkinek az eddigi segítséget!

A connection.send bejött, meg azt hiszem, értem is, miért azt kell használni :)

A "beszélgetés" már megy a két eszköz között, most a Wireshark-kal lehallgatott forgalomból próbálom megfejteni, hogy a telefon mennyi adatot küld, azt hogyan tagolja, és hogyan lehetne kibogarászni belőle a szenzorok által küldött értékeket

Írtam a fejlesztőnek is, de egyelőre (kedd, vagy szerda óta) nem válaszolt.

Tök jó látni, ahogy - még ha segítséggel is - de alakul a dolog :)
<-------
You can't grep on dead trees.