s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
12
print('Socket created')
13
s.bind(('', port_TCP))
14
s.listen(1)
15
try:
16
while True:
17
komm, addr = s.accept()
18
while True:
19
command = komm.recv(1024)
20
if not command:
21
komm.close
22
break
23
print 'Nachricht [%s]: %s' % (addr[0], command)
24
komm.send('Befehl erhalten: ' + command)
25
if command == 'NULL':
26
komm.close()
27
28
finally:
29
s.close()
30
31
print(command)
32
print ('123')
33
raw_input('Eingabe...')
Ich möchte einmal einen Befehl per TCP an diesen Server senden (Mache
ich zwekcs Testzwekce per Packet Sender) und danach soll er die
Verbindung beenden und im Programmcode fortfahren.
Wenn er den Befehl (Vier Buchstaben) erhált wird dieser Befehl richtig
zurückgesendet, dann wird aber nichts mehr gemacht. Ich kann danach
einfach weitere Befehle senden. Das will ich aber nicht mehr. Er soll
dann die Ausgabe unten machen.
Hmm, ich kenn zwar python nicht, aber
- wofür benutzt Du 2 verschachtelte Schleifen? / was bedeutet "while
True" für Dich?
- Kommt nach einem Try nicht ein "catch" / except ?
Sven schrieb:> Ich möchte einmal einen Befehl per TCP an diesen Server senden (Mache> ich zwekcs Testzwekce per Packet Sender) und danach soll er die> Verbindung beenden und im Programmcode fortfahren.
Das ist jetzt schon die zweite Frage, in der Du irgendwelche komischen
Sachen mit Deinem Netzwerk machst. Magst Du uns nicht vielleicht einmal
erzählen, was Du eigentlich vorhast?
Was den Code angeht, so ist er an zwei Stellen kaputt. Auf den ersten
Fehler hat "Rainer Unsinn" Dich bereits hingewiesen, nämlich: was
bedeutet "while True" für Dich? Und zweitens: was ist "komm.close"?
Sheeva P. schrieb:> Sven schrieb:>> Ich möchte einmal einen Befehl per TCP an diesen Server senden (Mache>> ich zwekcs Testzwekce per Packet Sender) und danach soll er die>> Verbindung beenden und im Programmcode fortfahren.>> Das ist jetzt schon die zweite Frage, in der Du irgendwelche komischen> Sachen mit Deinem Netzwerk machst. Magst Du uns nicht vielleicht einmal> erzählen, was Du eigentlich vorhast?>> Was den Code angeht, so ist er an zwei Stellen kaputt. Auf den ersten> Fehler hat "Rainer Unsinn" Dich bereits hingewiesen, nämlich: was> bedeutet "while True" für Dich? Und zweitens: was ist "komm.close"?
Ich erhalte einen Befehl per TCP. Diesen muss ich auswerten und
anschlißend entsprechnd einen Befehl per UDP weitersenden. Deshalb nur
einen Befehl erhalten per TCP. Das hab ich jetzt auch soweit
hinbekommen. Diesen Befehl muss ich jetzt auswerten. Problem dabei gerad
ist das ich zum Beispiel
CAEE
bekomme. Wenn ich jetzt folgende Abfrage machen will
if (command[0] == 'C')
kommt immer die Meldung: IndexError: string index out of range
Was muss ich tun damit das tut. Bin leider absoluter Neuling in Python.
Zu 1:
Wenn du den Socket schließen möchtest, solltest du nach dem
erfolgreichem Empfangen deines Strings die while Schleife verlassen.
(Stichwort break)
Zu 2:
Du übergibst deiner if Abfrage gerade einen leeren String, und das mag
sie nicht...
Hierzu ein kleines Beispiel (Python 3.x)
Anhand dieses Codefetzens wird dir wahrscheinlich kaum jemand
helfen können. An welcher Stelle hast du diese Zeile eingefügt?
Ganzen Code zeigen.
PS: Die Bedingung brauchst du nicht in Klammern einzuschließen.
Bernhard R. schrieb:> Zu 1:> Wenn du den Socket schließen möchtest, solltest du nach dem> erfolgreichem Empfangen deines Strings die while Schleife verlassen.> (Stichwort break)>> Zu 2:> Du übergibst deiner if Abfrage gerade einen leeren String, und das mag> sie nicht...>> Hierzu ein kleines Beispiel (Python 3.x)def testing(str):> print("Testing: " + str)> if str[0] == 'A':> print("got it!")>> testing('AFFE')> testing('DOOF')> testing('')>> Viel Erfolg,>> Bernhard
Ich verwende Python 2.7. Funktioniert das dann trotzdem so wie in deinem
Beispiel gezeigt.
Hier nochmal der ganze Code.
Sorry für den Doppelpost.
@Bernhard: Hab dein Beispiel kurz getestet. Das versteh ich soweit. Aber
ich erhalte doch per TCP keinen leeren String sondern in der Variable
command steht doch etwas drinne.
Grüsse
Bernhard R. schrieb:> Ob du wirklich keinen leeren string bekommst würde ich mal> testen:if command == '':> print('empty string!!!')> else:> #break the while loop> break>> Ansonsten tut das Code Snippet bei mir ...Bernhard R. schrieb:> Ob du wirklich keinen leeren string bekommst würde ich mal> testen:if command == '':> print('empty string!!!')> else:> #break the while loop> break>> Ansonsten tut das Code Snippet bei mir ...
Also ich erhalte tatsächlich einen leeren String. Dann ist klar das die
Fehlermeldung kommt. Aber weiter oben im Code gebe ich ja das command
aus, also den Inhalt welchen ich erhalten habe. Dann kann der ja
eigentlich gar nicht leer sein. Außer das er nicht übergeben wird.
Vielleicht pack ich das ganze mal in eine Funktion und übergebe am ende
das command mit "return command"
Oder hast du noch eine andere Lösung bzw. den Fehler
Ich habs gerade nochmal mit netcat versucht.
Ein leerer String sendet mir trotzdem ein 0x0a (line feed) mit.
Teste das mal mit print(command.__len__()).
Bei mir kam 1 raus...
Sven schrieb:> while 1:> command = (komm.recv(1024))> if not command:> komm.close> break
Du springst hier aus der while-Schleife, wenn "command" leer ist!
Das dürfte das Gegenteil von dem sein, was du eigentlich willst.
Sven schrieb:> Ich erhalte einen Befehl per TCP. Diesen muss ich auswerten und> anschlißend entsprechnd einen Befehl per UDP weitersenden.
Das hatte ich gestern schon verstanden. ;-)
Nein, im Ernst: Dein per TCP erhaltener Befehl kommt ja irgendwo her,
also vermutlich von einem anderen Netzwerkgerät. Die Auswertung dieses
Befehls hat vermutlich einen Sinn wie etwa eine Filterung oder
Konvertierung. Und das Weitersenden des Befehls dürfte doch vermutlich
irgendein Ziel haben, möglicherweise ein anderes Netzwerkgerät. Sind
meine Vermutungen soweit richtig? Wenn ja: gut, wenn nicht: bitte
korrigiere mich.
Um Dir jetzt einen vernünftigen Rat zu geben, wäre es durchaus sinnvoll,
etwas mehr über den Hintergrund Deiner Fragestellung zu erfahren. Also
beispielsweise, um welche Art von Netzwerkgeräten es bei dem TCP-Client
und dem UDP-Server geht, wie die Auswertung aussehen soll, und welchen
tieferen Sinn die ganze Veranstaltung haben soll. Anders gesagt: mit ein
wenig mehr Hintergrundinformationen könnte man Dir wesentlich schneller
und zweifellos auch besser helfen.
> Deshalb nur einen Befehl erhalten per TCP.
Siehst Du, da geht (für mich) die Unsicherheit schon los: was genau
meinst Du damit? Willst Du genau einen Befehl per TCP erhalten, diesen
auswerten, und dann den TCP-Server beenden? Oder soll der TCP-Server
nach Empfang und Auswertung des Befehls auf weitere Befehle lauschen?
Dabei stellt sich eine Reihe weiterer Fragen, zum Beispiel, ob es
möglich ist, daß der TCP-Server mehrere Befehle gleichzeitig, oder
sonstwie einen zweiten Befehl erhält, bevor der erste fertig ausgewertet
und verarbeitet ist? Ob der UDP-Server, an den Du Deine Weiterleitung
schickst, Dir eine Bestätigung zurückschickt, daß er Deinen
weitergeleiteten Befehl empfangen hat? Warum Du wegen im Prinzip
derselben Frage noch einen zweiten Thread eröffnest, obwohl Du Dich im
ersten Thread nicht mehr gemeldet hast?
> Das hab ich jetzt auch soweit hinbekommen.
Sei mir nicht böse, aber Dein Code sieht für mich nicht danach aus, als
ob Du das zuverlässig hinbekommen hättest. ;-)
> Was muss ich tun damit das tut. Bin leider absoluter Neuling in Python.
Ich bin mir ehrlich gesagt nicht ganz sicher, ob Netzwerkprogrammierung
wirklich der beste Weg ist, um eine Programmiersprache zu lernen.
Bernhard R. schrieb:> Ich habs gerade nochmal mit netcat versucht.> Ein leerer String sendet mir trotzdem ein 0x0a (line feed) mit.> Teste das mal mit print(command.__len__()).
Es gilt als sehr schlechter Stil, Variablen, Funktionen und Operatoren
zu benutzen, die per Konvention "private" sind. Daher lieber nicht
Sheeva P. schrieb:> Sven schrieb:>> Nein, im Ernst: Dein per TCP erhaltener Befehl kommt ja irgendwo her,> also vermutlich von einem anderen Netzwerkgerät. Die Auswertung dieses> Befehls hat vermutlich einen Sinn wie etwa eine Filterung oder> Konvertierung. Und das Weitersenden des Befehls dürfte doch vermutlich> irgendein Ziel haben, möglicherweise ein anderes Netzwerkgerät. Sind> meine Vermutungen soweit richtig? Wenn ja: gut, wenn nicht: bitte> korrigiere mich.>> Um Dir jetzt einen vernünftigen Rat zu geben, wäre es durchaus sinnvoll,> etwas mehr über den Hintergrund Deiner Fragestellung zu erfahren. Also> beispielsweise, um welche Art von Netzwerkgeräten es bei dem TCP-Client> und dem UDP-Server geht, wie die Auswertung aussehen soll, und welchen> tieferen Sinn die ganze Veranstaltung haben soll. Anders gesagt: mit ein> wenig mehr Hintergrundinformationen könnte man Dir wesentlich schneller> und zweifellos auch besser helfen.>>> Deshalb nur einen Befehl erhalten per TCP.>> Siehst Du, da geht (für mich) die Unsicherheit schon los: was genau> meinst Du damit? Willst Du genau einen Befehl per TCP erhalten, diesen> auswerten, und dann den TCP-Server beenden? Oder soll der TCP-Server> nach Empfang und Auswertung des Befehls auf weitere Befehle lauschen?>> Dabei stellt sich eine Reihe weiterer Fragen, zum Beispiel, ob es> möglich ist, daß der TCP-Server mehrere Befehle gleichzeitig, oder> sonstwie einen zweiten Befehl erhält, bevor der erste fertig ausgewertet> und verarbeitet ist? Ob der UDP-Server, an den Du Deine Weiterleitung> schickst, Dir eine Bestätigung zurückschickt, daß er Deinen> weitergeleiteten Befehl empfangen hat? Warum Du wegen im Prinzip> derselben Frage noch einen zweiten Thread eröffnest, obwohl Du Dich im> ersten Thread nicht mehr gemeldet hast?
Hallo,
also nochmal etwas genauer vielleicht. Der TCP Client ist momentan noch
nicht ausgereift, dient aber nur dazu Befehle zu senden bzw. wie du
schon gesagt hast am Ende eine quittierung zu erhalten. Deshalb kann ich
hier im ersten Schritt mit dem Programm Packet Sender arbeiten.
Es ist so das ich eben einen Befehl sende (z.B. CAII) welcher für
Konfiguration all steht. Dann soll dieser Befehl von meinem TCP Server
empfangen werden. Außerdem muss ich über diesen TCP Server vermutlich zu
aller erst eine IP Adresse senden, welches Gerät konfiguriert werden
muss. Das ganze befindet sich später an einem Computer alles, also nicht
übers Local-Netz hinaus soweit ich das verstanden habe.
So der Befehl bzw. die IP Adresse werden dann verwendet um einen
definierten Befehl (den weiß ich selbst noch nicht so genau) im nächsten
schritt per UDP an einen zweiten Client so senden. Hier handelt es sich
um einen Sensor der angesprochen und konfiguriert wird bzw. auch
ausgelesen werden kann. Ist der befehl dort angekommen wird automatisch
der befehl vom Sensor quittiert und per UDP wieder empfangen. Diese
Quittierung soll dann wieder an den TCP Client gesendet werdern so das
dieser weiß, der Befehl wurde ausgeführt.
Ic hoffe ich konnte damit etwas licht ins dunkle bringen. Habe leider
immer noch keine Lösung für mein Problem mit der variable "command".
Grüße
print('Socket created\nWaiting for Communication to Client')
18
receive.bind(('', port_TCP))
19
receive.listen(1)
20
21
komm, addr = receive.accept()
22
print('Connection adress is: [%s]' % (addr[0]))
23
while 1:
24
command = (komm.recv(1024))
25
print 'Command: %s' % (command)
26
komm.send('Befehl erhalten: ' + command)
27
print 'Command: %s' % (command)
28
if command[0] == 'C':
29
funktion_1()
30
break
31
elif command[0] == 'A':
32
funktion_2()
33
break
34
else:
35
print('wrong')
36
break
So erkennt er jetzt ohne Probleme ob zum Beispiel ein C oder ein A vorne
steht. Das bedeutet doch das ich in die Funktion_1 dann meine weiteren
Aufgaben schreiben kann. Oder gibt es einen besseren weg? Durch das
break wird ja anschließend die while Schleife beendet. Aber meine TCP
Verbindung ja eigentlich nicht? Macht es sinn diese zu beenden und beim
senden der quittierung die verbindung neu aufzubauen oder kann ich diese
problemlos offen halten und trotzdem eine UDP verbindung aufmachen und
senden? Quasi am Ende dann meine Verbindungen erst alle schließen?
Grüße
Warum nimmst du nicht zumindest für die TCP Verbindung einen
SocketServer, dieser sollte die das TCP Handling abnehmen und du kannst
dich um das erkennen der Befehle und das UDP handling kümmern. Außerdem
finde ich dein if command[0] == 'C': sieht sehr nach basteln aus :)
ich würde dir hier vorschlagen ein dict zu verwenden key ist der gültige
Befehl und value ist die dann zu rufende funktion. denn Funktionen sind
in Python auch nur Objekte d.h. du kannst sie auch so verwenden.
1
import SocketServer
2
3
4
class MyTCPHandler(SocketServer.BaseRequestHandler):
5
def handle(self):
6
command = { 'A': function1,
7
'B': function2}
8
exit = False
9
try:
10
while not exit:
11
self.data = self.request.recv(1024).strip()
12
if 'exit' in self.data.lower():
13
exit = True
14
elif len(self.data) < 1:
15
continue
16
else:
17
try:
18
# detect command
19
cmd = command[self.data]
20
except KeyError:
21
print 'Unkown Command %s' % self.data
22
else:
23
# call associated function if cmd was found.
24
cmd()
25
# tell client execution is done
26
self.request.sendall('Execution done')
27
except Exception as e:
28
print('Error : {}'.format(e))
29
30
31
def function1():
32
print 'A is here'
33
34
def function2():
35
print 'B is here'
36
37
if __name__ == "__main__":
38
HOST, PORT = "", 9999
39
40
SocketServer.TCPServer.allow_reuse_address = True
41
# Create the server, binding to localhost on port 9999
42
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
43
44
# Activate the server; this will keep running until you
45
# interrupt the program with Ctrl-C
46
server.serve_forever()
das ist eigentlich nur das SocketServer example mit ein wenig
Anpassungen im handle auf deine Bedürfnisse.
Hier ist der handle nochmal ein wenig umgebaut, und entspricht etwas
mehr dem was dein Code macht. Der Server macht nach jeden Befehl die
Verbindung zu und kann mit Befehlen, wie dem oben erwähnten 'CAEE'
umgehen. Wobei die for-schleife davon ausgeht das CAEE bedeutet führe C
dann A, E, E aus.