Python实现WEB详细过程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用Websocket对于客户端来说无疑十分简单。websocket提供了三个简单的函数,onopen,onclose以及onmessage,顾名思义,他们分别监听socket的开启、断开和消息状态。
例如在一个WebSocket的客户端例子中,你可以这样写:
window.onload = function() {
var s = new WebSocket(“ws://localhost:8000/”);
s.onopen = function(e) { alert(“opened”); }
s.onclose = function(e) { alert(“closed”); }
s.onmessage = function(e) { alert(“got: ” + e.data); }
};
在代码中,首先创建了一个新的socket,指向websocket服务器端:
var s = new WebSocket(“ws://localhost:8000/”);
然后利用三个基本函数实现状态监听。
当然这个例子并不完善,它参考了麻省理工一位研究生Mr. Yang的文章(/wp/web-sockets-tutorial-with-simple-python- server/),而你如果需要更好的客户端测试代码,可以看这里:http://cl.ly/3N3Y3t2s3U1v1h0A433u我们在新的代码里提供了完成的和服务器交互数据的功能,发送数据我们使用的函数是send(),你可以在代码中看到。
我们之所以不直接引用Yang的文章是因为Yang对服务器的理解不够完善,或者用他的话来说就是outdate。
感谢Yang为我们提供了一个简单的socket server的例子,不过可惜放在现在来说它是有问题的,当然我们还是把例子引述如下:
#!/usr/bin/env python
import socket, threading, time
def handle(s):
print repr(s.recv(4096))
s.send(”‟
HTTP/1.1 101 Web Socket Protocol Handshake\r
Upgrade: WebSocket\r
Connection: Upgrade\r
WebSocket-Origin: http://localhost:8888\r
WebSocket-Location: ws://localhost:9876/\r
WebSocket-Protocol: sample
”‟.strip() + …\r\n\r\n‟)
time.sleep(1)
s.send(…\x00hello\xff‟)
time.sleep(1)
s.send(…\x00world\xff‟)
s.close()
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((”, 9876));
s.listen(1);
while 1:
t,_ = s.accept();
threading.Thread(target = handle, args = (t,)).start()
虽然不符合我的风格,不过作为python代码来说依然是极具优美。
我们可以看到,Yang在代码中首先创建了一个socket,然后进行握手,此处的例子是:
s.send(”‟
HTTP/1.1 101 Web Socket Protocol Handshake\r
Upgrade: WebSocket\r
Connection: Upgrade\r
WebSocket-Origin: http://localhost:8888\r
WebSocket-Location: ws://localhost:9876/\r
WebSocket-Protocol: sample
”‟.strip() + …\r\n\r\n‟)
向客户端发送了这样一串字符串作为data的head信息以完成握手。当然如果你认真的去测试了Yang的例子,就会发现这样做是不规范的,或者说是不符合当前的Websocket协议的。
控制台会反馈给你这样的信息:
miss head: Sec-WebSocket-Local
miss head: sec-WebSocket-Origin
这是因为,在第76和77版的websocket协议中,握手远非Yang所做的这般简单。
在draft protocol 76中,具体的握手要求如下
1.Client应从WebSocket-Origin发送head包到WebSocket-Location
2.客户端发送的包结构应该是包括Host,Origin,Sec-WebSocket-Key1,Sec-WebSocket-Key2等信息:
这是我们截取的一个例子:
…GET / HTTP/1.1\r\n
Upgrade: WebSocket\r\n
Connection: Upgrade\r\n
Host: localhost:9876\r\n
Origin: http://127.0.0.1\r\n
Sec-WebSocket-Key1: c 33w ^T5 1 1C72 ~66 I E=r 8\r\n
Sec-WebSocket-Key2: 354214h9998 f \r\n
3.服务器断获取包后,应该提取总长度为20的sec-websocket-key,然后进行如下计算:
For each of these fields, the server has to take the digits from the value to obtain a number (in this case 1868545188 and 1733470270 respectively), then divide that number by the number of spaces characters in the value (in this case 12 and 10) to obtain a 32-bit number (155712099 and 173347027). These two resulting numbers are then used in the server handshake, as described below.
既首先把以上字符串转化成数字,然后再计算key中的空格数目,并用key值除以空格数得到最后key值。
4.发送包含以下信息的head给client,完成握手,这里我直接贴出代码。
csock.send(“HTTP/1.1 101 WebSocket Protocol Handshake\r\n”)
csock.send(“Upgrade: WebSocket\r\n”)
csock.send(“Connection: Upgrad e\r\n”)
csock.send(“Sec-WebSocket-Origin: http://”+origin+”\r\n”)
csock.send(“Sec-WebSocket-Location: ws://”+host+”:”+str(port)+”/\r\n”)
csock.send(“Sec-WebSocket-Protocol: chat\r\n”)
csock.send(“\r\n”)
5.在完成握手即可进行数据交互,特别注意的是数据发送应当以0X00开头以0Xff结尾:
因而建议最好采用一个诸如这样的函数
def send(data):
first_byte = chr(0×00)
payload = data.encode(…utf-8′)