web-dev-qa-db-fra.com

Python programmation serveur / client socket

Donc je me lance dans python et j'essaye quelques trucs. Pour commencer, je crée un serveur qui fait des trucs simples comme le texte stocké de "GET", le nouveau texte de "STORE" sur le ancien texte stocké et "TRADUIRE" le texte en minuscules en majuscules. Mais j'ai quelques questions. Voici mon code jusqu'à présent:

import socket

Host = ''   # Symbolic name meaning the local Host
PORT = 24069    # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
    s.bind((Host, PORT))
except socket.error , msg:
    print 'Bind failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
    sys.exit()
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'
while 1:
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])
    data = conn.recv(1024)
    reply = 'OK...' + data
    if not data: break
    conn.send(data)
conn.close()
s.close()

Pour commencer à changer le texte d'un client en majuscules, d'après mes autres connaissances en programmation, je suppose que je stockerais le texte du client dans une variable, puis exécuterais une fonction dessus pour le changer en majuscule. Existe-t-il une telle fonction en python? Quelqu'un pourrait-il me donner un extrait de ce à quoi cela ressemblerait?

Et enfin, comment pourrais-je faire quelque chose comme GET ou STORE en python? Ma meilleure supposition serait:

data = conn.recv(1024)
if data == GET: print text
if data == STORE: text = data #Not sure how to reference the text that the client has entered

Merci beaucoup pour toute aide! :)

Note pour moi-même:

import socket

Host = ''   # Symbolic name meaning the local Host
PORT = 24069    # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
    s.bind((Host, PORT))
except socket.error , msg:
    print 'Bind failed. Error code: ' + str(msg[0]) + 'Error message: ' + msg[1]
    sys.exit()
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'

# Accept the connection
(conn, addr) = s.accept()
print 'Server: got connection from client ' + addr[0] + ':' + str(addr[1])
storedText = 'Hiya!'
while 1:
    data = conn.recv(1024)
    tokens = data.split(' ', 1)
    command = tokens[0]
    if command == 'GET':
        print addr[0] + ':' + str(addr[1]) + ' sends GET'
        reply = storedText
    Elif command == 'STORE':
        print addr[0] + ':' + str(addr[1]) + ' sends STORE'  
        storedText = tokens[0]
        reply = '200 OK\n' + storedText
    Elif command == 'TRANSLATE':
        print addr[0] + ':' + str(addr[1]) + ' sends TRANSLATE'
        storedText = storedText.upper()
        reply = storedText
    Elif command == 'EXIT':
        print addr[0] + ':' + str(addr[1]) + ' sends EXIT'
        conn.send('200 OK')
        break
    else:
        reply = '400 Command not valid.'

    # Send reply
    conn.send(reply)
conn.close()
s.close()
11
Katie Jurek

Je vois que vous êtes assez nouveau pour Python. Vous pouvez essayer de trouver un exemple de code et vous devriez également apprendre à interpréter le message d'erreur. Le message d'erreur vous donnera le numéro de ligne où vous devriez regarder. Vous devriez considérer cette ligne ou la ligne précédente, car l'erreur peut être causée par des erreurs précédentes.

Quoi qu'il en soit, après vos modifications, avez-vous toujours une erreur d'indentation?

Sur votre vraie question, d'abord, le concept.

Pour exécuter le client/serveur, vous aurez besoin de deux scripts: un en tant que client et un en tant que serveur.

Sur le serveur, le script devra simplement se lier à une socket et écouter cette connexion, recevoir des données, traiter les données puis retourner le résultat. C'est ce que vous avez fait correctement, sauf que vous avez juste besoin de traiter les données avant d'envoyer la réponse.

Pour commencer, vous n'avez pas besoin d'inclure le accept dans la boucle while, acceptez simplement une connexion, puis restez avec elle jusqu'à la fermeture du client.

Vous pouvez donc faire quelque chose comme ça sur le serveur:

# Accept the connection once (for starter)
(conn, addr) = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
stored_data = ''
while True:
    # RECEIVE DATA
    data = conn.recv(1024)

    # PROCESS DATA
    tokens = data.split(' ',1)            # Split by space at most once
    command = tokens[0]                   # The first token is the command
    if command=='GET':                    # The client requests the data
        reply = stored_data               # Return the stored data
    Elif command=='STORE':                # The client want to store data
        stored_data = tokens[1]           # Get the data as second token, save it
        reply = 'OK'                      # Acknowledge that we have stored the data
    Elif command=='TRANSLATE':            # Client wants to translate
        stored_data = stored_data.upper() # Convert to upper case
        reply = stored_data               # Reply with the converted data
    Elif command=='QUIT':                 # Client is done
        conn.send('Quit')                 # Acknowledge
        break                             # Quit the loop
    else:
        reply = 'Unknown command'

    # SEND REPLY
    conn.send(reply)
conn.close() # When we are out of the loop, we're done, close

et chez le client:

import socket

Host = ''   # Symbolic name meaning the local Host
PORT = 24069    # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((Host,PORT))
while True:
    command = raw_input('Enter your command: ')
    if command.split(' ',1)[0]=='STORE':
        while True:
            additional_text = raw_input()
            command = command+'\n'+additional_text
            if additional_text=='.':
                break
    s.send(command)
    reply = s.recv(1024)
    if reply=='Quit':
        break
    print reply

Exemple d'exécution (exécutez d'abord le serveur, puis exécutez le client) sur la console client:

 Entrez votre commande: STORE ceci est un texte 
 OK 
 Entrez votre commande: GET 
 Ceci est un texte 
 Entrez votre commande: TRADUIRE 
 CECI IS UN TEXTE 
 Entrez votre commande: OBTENEZ 
 CECI IS UN TEXTE 
 Entrez votre commande: QUIT 

J'espère que vous pourrez continuer à partir de là.

Un autre point important est que vous utilisez TCP (socket.SOCK_STREAM), Afin que vous puissiez réellement conserver la connexion après l'avoir acceptée avec s.accept(), et vous ne doit la fermer que lorsque vous avez accompli la tâche sur cette connexion (l'acceptation d'une nouvelle connexion a son surcoût). Votre code actuel ne pourra gérer qu'un seul client. Mais, je pense que pour commencer, c'est assez bien. Après avoir confiant avec cela, vous pouvez essayer de gérer plus de clients en utilisant threading .

13
justhalf