2013-02-07 11 views
21

Próbuję uruchomić ten prosty WebSocket w Pythonie, z kilkoma drobnymi zmianami. Używam Pythona w wersji 2.4.3, ponieważ nie mogę użyć nowszej wersji, ale nie jestem pewien, ile to ma znaczenie.Serwer WebSocket w Pythonie: obiekt 'module' nie ma atrybutu 'AF_INET'

Oto błąd Dostaję:

Traceback (most recent call last): 
    File "socket.py", line 258, in ? 
    server = WebSocketServer("localhost", 8000, WebSocket) 
    File "socket.py", line 205, in __init__ 
    self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
AttributeError: 'module' object has no attribute 'AF_INET' 

I tu jest mój kod:

import time 
import struct 
import socket 
import base64 
import sys 
from select import select 
import re 
import logging 
from threading import Thread 
import signal 

# Simple WebSocket server implementation. Handshakes with the client then echos back everything 
# that is received. Has no dependencies (doesn't require Twisted etc) and works with the RFC6455 
# version of WebSockets. Tested with FireFox 16, though should work with the latest versions of 
# IE, Chrome etc. 
# 
# [email protected] 
# Adapted from https://gist.github.com/512987 with various functions stolen from other sites, see 
# below for full details. 

# Constants 
MAGICGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 
TEXT = 0x01 
BINARY = 0x02 


# WebSocket implementation 
class WebSocket(object): 

    handshake = (
     "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" 
     "Upgrade: WebSocket\r\n" 
     "Connection: Upgrade\r\n" 
     "Sec-WebSocket-Accept: %(acceptstring)s\r\n" 
     "Server: TestTest\r\n" 
     "Access-Control-Allow-Origin: http://localhost\r\n" 
     "Access-Control-Allow-Credentials: true\r\n" 
     "\r\n" 
    ) 


    # Constructor 
    def __init__(self, client, server): 
     self.client = client 
     self.server = server 
     self.handshaken = False 
     self.header = "" 
     self.data = "" 


    # Serve this client 
    def feed(self, data): 

     # If we haven't handshaken yet 
     if not self.handshaken: 
      logging.debug("No handshake yet") 
      self.header += data 
      if self.header.find('\r\n\r\n') != -1: 
       parts = self.header.split('\r\n\r\n', 1) 
       self.header = parts[0] 
       if self.dohandshake(self.header, parts[1]): 
        logging.info("Handshake successful") 
        self.handshaken = True 

     # We have handshaken 
     else: 
      logging.debug("Handshake is complete") 

      # Decode the data that we received according to section 5 of RFC6455 
      recv = self.decodeCharArray(data) 

      # Send our reply 
      self.sendMessage(''.join(recv).strip()); 


    # Stolen from http://www.cs.rpi.edu/~goldsd/docs/spring2012-csci4220/websocket-py.txt 
    def sendMessage(self, s): 
     """ 
     Encode and send a WebSocket message 
     """ 

     # Empty message to start with 
     message = "" 

     # always send an entire message as one frame (fin) 
     b1 = 0x80 

     # in Python 2, strs are bytes and unicodes are strings 
     if type(s) == unicode: 
      b1 |= TEXT 
      payload = s.encode("UTF8") 

     elif type(s) == str: 
      b1 |= TEXT 
      payload = s 

     # Append 'FIN' flag to the message 
     message += chr(b1) 

     # never mask frames from the server to the client 
     b2 = 0 

     # How long is our payload? 
     length = len(payload) 
     if length < 126: 
      b2 |= length 
      message += chr(b2) 

     elif length < (2 ** 16) - 1: 
      b2 |= 126 
      message += chr(b2) 
      l = struct.pack(">H", length) 
      message += l 

     else: 
      l = struct.pack(">Q", length) 
      b2 |= 127 
      message += chr(b2) 
      message += l 

     # Append payload to message 
     message += payload 

     # Send to the client 
     self.client.send(str(message)) 


    # Stolen from http://stackoverflow.com/questions/8125507/how-can-i-send-and-receive-websocket-messages-on-the-server-side 
    def decodeCharArray(self, stringStreamIn): 

     # Turn string values into opererable numeric byte values 
     byteArray = [ord(character) for character in stringStreamIn] 
     datalength = byteArray[1] & 127 
     indexFirstMask = 2 

     if datalength == 126: 
      indexFirstMask = 4 
     elif datalength == 127: 
      indexFirstMask = 10 

     # Extract masks 
     masks = [m for m in byteArray[indexFirstMask : indexFirstMask+4]] 
     indexFirstDataByte = indexFirstMask + 4 

     # List of decoded characters 
     decodedChars = [] 
     i = indexFirstDataByte 
     j = 0 

     # Loop through each byte that was received 
     while i < len(byteArray): 

      # Unmask this byte and add to the decoded buffer 
      decodedChars.append(chr(byteArray[i]^masks[j % 4])) 
      i += 1 
      j += 1 

     # Return the decoded string 
     return decodedChars 


    # Handshake with this client 
    def dohandshake(self, header, key=None): 

     logging.debug("Begin handshake: %s" % header) 

     # Get the handshake template 
     handshake = self.handshake 

     # Step through each header 
     for line in header.split('\r\n')[1:]: 
      name, value = line.split(': ', 1) 

      # If this is the key 
      if name.lower() == "sec-websocket-key": 

       # Append the standard GUID and get digest 
       combined = value + MAGICGUID 
       response = base64.b64encode(combined.digest()) 

       # Replace the placeholder in the handshake response 
       handshake = handshake % { 'acceptstring' : response } 

     logging.debug("Sending handshake %s" % handshake) 
     self.client.send(handshake) 
     return True 

    def onmessage(self, data): 
     #logging.info("Got message: %s" % data) 
     self.send(data) 

    def send(self, data): 
     logging.info("Sent message: %s" % data) 
     self.client.send("\x00%s\xff" % data) 

    def close(self): 
     self.client.close() 


# WebSocket server implementation 
class WebSocketServer(object): 

    # Constructor 
    def __init__(self, bind, port, cls): 
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.socket.bind((bind, port)) 
     self.bind = bind 
     self.port = port 
     self.cls = cls 
     self.connections = {} 
     self.listeners = [self.socket] 

    # Listen for requests 
    def listen(self, backlog=5): 

     self.socket.listen(backlog) 
     logging.info("Listening on %s" % self.port) 

     # Keep serving requests 
     self.running = True 
     while self.running: 

      # Find clients that need servicing 
      rList, wList, xList = select(self.listeners, [], self.listeners, 1) 
      for ready in rList: 
       if ready == self.socket: 
        logging.debug("New client connection") 
        client, address = self.socket.accept() 
        fileno = client.fileno() 
        self.listeners.append(fileno) 
        self.connections[fileno] = self.cls(client, self) 
       else: 
        logging.debug("Client ready for reading %s" % ready) 
        client = self.connections[ready].client 
        data = client.recv(4096) 
        fileno = client.fileno() 
        if data: 
         self.connections[fileno].feed(data) 
        else: 
         logging.debug("Closing client %s" % ready) 
         self.connections[fileno].close() 
         del self.connections[fileno] 
         self.listeners.remove(ready) 

      # Step though and delete broken connections 
      for failed in xList: 
       if failed == self.socket: 
        logging.error("Socket broke") 
        for fileno, conn in self.connections: 
         conn.close() 
        self.running = False 

# Entry point 
if __name__ == "__main__": 

    logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s") 
    server = WebSocketServer("localhost", 8000, WebSocket) 
    server_thread = Thread(target=server.listen, args=[5]) 
    server_thread.start() 

    # Add SIGINT handler for killing the threads 
    def signal_handler(signal, frame): 
     logging.info("Caught Ctrl+C, shutting down...") 
     server.running = False 
     sys.exit() 
    signal.signal(signal.SIGINT, signal_handler) 

    while True: 
     time.sleep(100) 
+0

zrobiłem ten sam błąd - bardzo się cieszę znalazłeś swoje pytanie! – drewwyatt

Odpowiedz

68

Wydaje się, że już nazwany własny plik socket.py, więc kiedy import socket, nie dostajesz biblioteki systemowej (po prostu zaimportujesz ponownie plik, w którym aktualnie się znajdujesz - który nie ma symbolu AF_INET). Spróbuj zmienić nazwę pliku, tak jak mysocket.py.

+5

Ugh ... co za głupi błąd. Dzięki! – Gus

+6

@Gus: są najtrudniejsze do zobaczenia :-) –

+0

@NickBastin Przybiłeś to - dziękuję. Naprawdę cieszę się, że znalazłem ten wpis. – drewwyatt

2

Miałem ten sam problem, dosłownie utknąłem tu przez wiele godzin, próbowałem zainstalować go milion razy, ale znalazłem rozwiązanie.

1) Upewnij się, że nazwa pliku nie jest socket.py,

2) Zmień katalog, to nie będzie działać w katalogu domowym z powodu pewnych kwestii uprawnień.

Jeśli masz przez anychance zapisany plik jako plik socket.py, nie kopiuj tego samego pliku lub zmień jego nazwę na coś innego, problem będzie się utrzymywał. Radzę ci zrobić, otwórz nowy folder w innym katalogu, napisz prosty kod gniazda, który dotyczył AF_INET. Spróbuj go uruchomić. Powinno działać.

+0

aaah .. Zrobiłem ten sam błąd, kopiując go do innej nazwy w tym samym katalogu! wszyscy nooby myślą podobnie! – ticktock

1

wprowadź aktualny katalog roboczy i usunąć pliki o nazwie „socket.py” i „socket.pyc”

15

Nawet po zmianie nazwy pliku, jeśli używasz Pythona z terminalu.

(można uzyskać ten sam błąd)

Uprzejmie

rm -rf socket.pyc

(wcześniej skompilowany kod bajtowy)

Powiązane problemy