La création d'un WebSocket Client en Python
Je suis en train d'apprendre sur socket de programmation ainsi que le protocole WebSocket. Je sais qu'il y a python web socket clients dans l'existence, mais je suis l'espoir de construire un jouet version pour mon propre apprentissage. Pour ce faire j'ai créé une extrêmement simple Tornade serveur websocket que je suis en cours d'exécution sur localhost:8888
. Tout ce qu'il fait est d'imprimer un message lorsqu'un client se connecte.
C'est l'ensemble du serveur et ça fonctionne (j'ai testé avec un petit script javascript dans mon navigateur)
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print('new connection')
self.write_message("Hello World")
def on_message(self, message):
print('message received %s' % message)
def on_close(self):
print('connection closed')
application = tornado.web.Application([
(r'/ws', WSHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()
Donc, une fois que je démarre le serveur j'essaie d'exécuter le script suivant
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((socket.gethostbyname('localhost'), 8888))
msg = '''GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13'''.encode('ascii')
print(len(msg))
sent_count = sock.send(msg)
print('sent this many bytes:', sent_count)
recv_value = sock.recv(1)
print('recvieved:', recv_value)
Ce que j'espère, c'est que le serveur va envoyer l'en-tête de réponse, comme spécifié dans la RFC. Au lieu de la chaussette.recv est suspendu. Cela m'amène à croire que le serveur n'est pas en reconnaissant les websocket poignée de main initiale. Cette poignée de main est tiré hors de la RFC. Je sais que le websocket clé doit être aléatoire et tout et tout, mais je ne pense pas que causerait le serveur d'ignorer la poignée de main (le websocket clé est valide). Je pense que je peux comprendre le reste une fois que je peux lancer la poignée de main donc j'espère qu'il y a une certaine incompréhension dans les websockets travail ou comment envoyer de la première handhake.
OriginalL'auteur Bear | 2013-06-08
Vous devez vous connecter pour publier un commentaire.
1) Lorsque vous envoyez un message sur un socket, vous n'avez aucune idée de combien de morceaux il sera divisé en. Il peut tout obtenir envoyé à la fois; ou les 3 premières lettres peuvent être envoyées, puis le reste du message; le message peut être divisé en 10 morceaux.
2) 1) comment le serveur est censé savoir qu'il a reçu tous les morceaux envoyés par le client? Par exemple, supposons que le serveur reçoit 1 morceau de message. Comment le serveur savoir si c'était là tout le message ou si il y a plus de 9 morceaux à venir?
3) je vous suggère de lire ceci:
http://docs.python.org/2/howto/sockets.html
(Ainsi que les liens dans les commentaires)
4) Maintenant, pourquoi n'êtes-vous pas à l'aide de python pour créer un serveur HTTP?
python3:
python2:
La SimpleHTTPRequestHandler sert les fichiers du serveur de répertoire du programme et au-dessous, correspondant à l'url de la requête à la structure de répertoire que vous créez. Si vous demandez '/', le serveur va servir d'un index.html fichier dans le même répertoire que le serveur est en. Voici un exemple d'un socket client pour python 3 (python 2 exemple ci-dessous):
En python 3, vous devez utiliser des chaînes d'octets avec des sockets, sinon vous obtiendrez la redoutable:
Ici, il est en python 2.x:
Notez que l'en-tête de la demande indique au serveur HTTP 1.1 est le protocole, c'est à dire les règles qui régissent la conversation. Et comme le RFC pour HTTP 1.1 décrit, il y a deux "\r\n' des séquences figurant dans la demande. Donc le serveur est à la recherche pour cette deuxième "\r\n' de la séquence. Si vous supprimez l'un de l' '\r\n' séquences à partir de la demande, le client s'accrocher sur le recv() parce que le serveur est toujours en attente pour plus de données, car le serveur n'a pas lu cette deuxième "\r\n' de la séquence.
Notez également que vous pourrez envoyer les données en octets(en python 3), donc il ne vont pas être tout automatique '\n' conversions, et le serveur s'attendent à ce que la séquence "\r\n'.
Ok, maintenant que vous êtes à quelque chose. Est le serveur attend un 0x00 octet pour signaler la fin du message? Ou est le serveur attend à voir "FIN DE MESSAGE"? Ou un saut de ligne? Chacun de ces régimes est connu comme un protocole, et vous devez être d'accord sur le protocole à l'avance, de sorte qu'une prise et un serveur de savoir comment parler les uns aux autres. Lire le lien que j'ai posté.
Ouais j'avais posté avant que votre lien. Mais ce que vous avez dit a du sens. Ce dont j'ai besoin à faire est de laisser le serveur sais que mon message est de sorte qu'il peut traiter/répondre. Je suis en train de lire le HOWTO maintenant donc j'espère que ça me met sur la bonne voie.
Prochaine lecture: 1) La définition d'une requête HTTP: w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5. Notez que la définition de la Ligne de Requête comprend un CRLF (qui est "\r\n' pour tous les OS ) à la fin de la ligne. En outre, le général de définition de la Demande nécessite un autre CRLF, qui peut venir après les en-têtes si présent. 2) un exemple d'un client python socket de connexion à un serveur http: binarytides.com/python-socket-programming-tutorial
Je vais vous lire chacun de ces ressources. Ils sont vraiment ce que je cherchais, et en espérant en apprendre plus sur (mon réseaux de classe, j'ai pris était complètement inutile et n'a pas parlé du tout de cela). La partie http aidera à voir la façon dont un client œuvres et d'étendre sur elle.
OriginalL'auteur 7stud