</pre><pre name="code" class="python">#coding=utf-8
from threading import Thread
import struct
import time
import hashlib
import base64
import socket
import time
class returnCrossDomain(Thread):
def __init__(self,connection):
Thread.__init__(self)
self.con = connection
self.isHandleShake = False
def run(self):
while True:
if not self.isHandleShake:
#开始握手阶段
header = self.analyzeReq()
secKey = header['Sec-WebSocket-Key'];
acceptKey = self.generateAcceptKey(secKey)
response = "HTTP/1.1 101 Switching Protocols\r\n"
response += "Upgrade: websocket\r\n"
response += "Connection: Upgrade\r\n"
response += "Sec-WebSocket-Accept: %s\r\n\r\n"%(acceptKey.decode('utf-8'))
self.con.send(response.encode())
self.isHandleShake = True
print('response:\r\n'+response)
#握手阶段结束
else:
#接受客户端数据
opcode = self.getOpcode()
if opcode == 8:
self.con.close()
self.getDataLength()
clientData = self.readClientData()
print('客户端数据:'+clientData)
#向客户端发送数据
self.sendDataToClient('hello world')
def analyzeReq(self):
reqData = self.con.recv(1024).decode()
reqList = reqData.split('\r\n')
headers = {}
for reqItem in reqList:
if ': ' in reqItem:
unit = reqItem.split(': ')
headers[unit[0]] = unit[1]
return headers
def generateAcceptKey(self,secKey):
sha1 = hashlib.sha1()
sha1.update((secKey+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11').encode())
sha1_result = sha1.digest()
acceptKey = base64.b64encode(sha1_result)
return acceptKey
def getOpcode(self):
first8Bit = self.con.recv(1)
first8Bit = struct.unpack('B',first8Bit)[0]
opcode = first8Bit & 0b00001111
return opcode
def getDataLength(self):
second8Bit = self.con.recv(1)
second8Bit = struct.unpack('B',second8Bit)[0]
masking = second8Bit >> 7
dataLength = second8Bit & 0b01111111
if dataLength <= 125:
payDataLength = dataLength
elif dataLength == 126:
payDataLength = struct.unpack('H',self.con.recv(2))[0]
elif dataLength == 127:
payDataLength = struct.unpack('Q',self.con.recv(8))[0]
self.masking = masking
self.payDataLength = payDataLength
def readClientData(self):
if self.masking == 1:
maskingKey = self.con.recv(4)
data = self.con.recv(self.payDataLength)
if self.masking == 1:
i = 0
trueData = ''
for d in data:
trueData += chr(d ^ maskingKey[i%4])
i += 1
return trueData
else:
return data
def sendDataToClient(self,text):
sendData = ''
sendData = struct.pack('!B',0x81)
length = len(text)
if length <= 125:
sendData += struct.pack('!B',length)
elif length <= 65536:
sendData += struct.pack('!B',126)
sendData += struct.pack('!H',length)
elif length == 127:
sendData += struct.pack('!B',127)
sendData += struct.pack('!Q',length)
sendData += struct.pack('!%ds' % (length),text.encode())
dataSize = self.con.send(sendData)
def main():
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(('127.0.0.1',88))
sock.listen(5)
while True:
try:
connection,address = sock.accept()
returnCrossDomain(connection).start()
except:
time.sleep(1)
if __name__=="__main__":
main()