




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、用python實現(xiàn)的websocket代碼ubuntu下python2.76windowsPython2.79,chrome37firefox35通過代碼是在別人(cddn有人提問)基礎上改的,主要改動了parsedat琲口sendmessage這2個函數(shù).改代碼參考下面了這段文檔.主要是第5條,發(fā)送的數(shù)據(jù)長度分別是8bit和16bit和64bit(即127,65535,和2A64-1)三種情況發(fā)送和收取是一樣的,例如1 .長度小于125時(由于使用126,127用作標志位.)2 .數(shù)據(jù)長度在128-65525之間時,PayloadLength位設為126,后面額外使用16bit表示長度(前面
2、的126不再是長度的一部分)3 .數(shù)據(jù)長度在65526-2A64-1之間時,PayloadLength位設為127,后面額外使用64bit表示長度(前面的127不再是長度的一部分)1. Fin(bit0):determinesifthisisthelastframeinthemessage.Thiswouldbesetto1ontheendofaseriesofframes,orinasingle-framemessage,itwouldbesetto1asitisboththefirstandlastframe.2. RSV1,RSV2,RSV3(bits1-3):thesethreebit
3、sarereservedforwebsocketextensions,andshouldbe0unlessaspecificextensionrequirestheuseofanyofthesebytes.3. Opcode(bits4-7):thesefourbitsdeteriminethetypeoftheframe.ControlframescommunicateWebSocketstate,whilenon-controlframescommunicatedata.Thevarioustypesofcodesinclude:1. x0:continuationframe;thisfr
4、amecontainsdatathatshouldbeappendedtothepreviousframe2. x1:textframe;thisframe(andanyfollowing)containstext3. x2:binaryframe;thisframe(andanyfollowing)containsbinarydata4. x3-x7:non-controlreservedframes;thesearereservedforpossiblewebsocketextensions5. x8:closeframe;thisframeshouldendtheconnection6.
5、 x9:pingframe7. xA:pongframe8. xB-xF:controlreservedframes4. Mask(bit8):thisbitdetermineswhetherthisspecificframeusesamaskornot.5. PayloadLength(bits9-15,or16-31,or16-79):thesesevenbytesdeterminethepayloadlength.Ifthelengthis126,thelengthisactuallydeterminedbybits16through31(thatis,thefollowingtwoby
6、tes).Ifthelengthis127,thelengthisactuallydeterminedbybits16through79(thatis,thefollowingeightbytes).6. MaskingKey(thefollowingfourbytes):thisrepresentsthemask,iftheMaskbitissetto1.7. PayloadData(thefollowingdata):finally,thedata.Thepayloaddatamaybesentovermultipleframes;weknowthesizeoftheentiremessa
7、gebythepayloadlengththatwassent,andcanappenddatatogethertoformasinglemessageuntilwereceivethemessagewiththeFinflag.Eachconsecutivepayload,ifitexists,willcontainthe0"continuationframe"opcode.具體代碼:pythonviewplaincopyC1. #coding=utf82. #!/usr/bin/python3.4.5. importstruct,socket6. importhashl
8、ib7. importthreading,random8. importtime9. importstruct10. frombase64importb64encode,b64decode11.12.13. connectionlist=14. g_code_length=015. g_header_length=016.17.18. defhex2dec(string_num):19. returnstr(int(string_num.upper(),16)3.24. defget_datalength(msg):25. globalg_code_length26. gl
9、obalg_header_length27.28. print(len(msg)29. g_code_length=ord(msg1)&12730. received_length=0;31. ifg_code_length=126:32. #g_code_length=msg2:433. #g_code_length=(ord(msg2)<<8)+(ord(msg3)34. g_code_length=struct.unpack>H',str(msg2:4)035. g_header_length=836. elifg_code_length=127:37.
10、 #g_code_length=msg2:1038. g_code_length=struct.unpack>Q',str(msg2:10)039.40.41.g_header_length = 14elseg_header_length = 642. g_code_length=int(g_code_length)43. returng_code_length44.45. defparse_data(msg):46. globalg_code_length47. g_code_length=ord(msg1)&12748. received_length=0;49. i
11、fg_code_length=126:50. g_code_length=struct.unpack>H',str(msg2:4)051. masks=msg4:852. data=msg8:53. elifg_code_length=127:54. g_code_length=struct.unpack>Q',str(msg2:10)055. masks=msg10:1456. data=msg14:57. else58. masks=msg2:659. data=msg6:60.61.62. i=063. raw_str=''64.65.66.
12、fordindata:67. raw_str+=chr(ord(d)Aord(masksi%4)68. i+=169.70.71. print(u”總長度是:%d"%int(g_code_length)2.72. returnraw_strdefsendMessage(message):globalconnectionlistmessage_utf_8=message.encode(f-8')forconnectioninconnectionlist.values():back_str=口back_str.appendx
13、81')data_length=len(message_utf_8)83.84.85. ifdata_length<=125:86. back_str.append(chr(data_length)87. elifdata_length<=65535:88. back_str.append(struct.packb',126)89. back_str.append(struct.pack>h',data_length)90. #back_str.append(chr(data_length>>8)91. #back_str.append(c
14、hr(data_length&0xFF)92. #a=struct.pack('>h',data_length)93. #b=chr(data_length>>8)94. #c=chr(data_length&0xFF)95. elifdata_length<=(2A64-1):96. #back_str.append(chr(127)97. back_str.append(struct.packb',127)98. back_str.append(struct.pack>q',data_length)99. #ba
15、ck_str.append(chr(data_length>>8)100. #back_str.append(chr(data_length&0xFF)101. else:102. print(u'太長了!)103. msg=''104. forcinback_str:105. msg+=c;106. back_str=str(msg)+message_utf_#!encode('utf-8')107. #connection.send(str.encode(str(u"x00%sxFFnn"%message)逮個
16、是舊版108. #print(u'sendmessage:'+message)109. ifback_str!=Noneandlen(back_str)>0:110. print(back_str)111. connection.send(back_str)112.113.114. defdeleteconnection(item):115. globalconnectionlist116. delconnectionlist'connection'+item117.118.119. classWebSocket(threading.Thread)#繼承T
17、hread120.121.122. GUID="258EAFA5-E914-47DA-95CA-C5AB0DC85B11"123.124.125. def_init_(self,conn,index,name,remote,path4”):41.142.143. ote) 53.154.)155.156.threading.Thread._init_(self#初始化父類Threa
18、dself.conn=connself.index==nameself.remote=remoteself.path=pathself.buffer=""self.buffer_utf8=""self.length_buffer=0defrun(self):#重載Thread的runprint('Socket%sStart!'%self.index)headers=self.handshaken=FalsewhileTrue:ifself.handshaken=False:print('Socket%s
19、StartHandshakenwith%s!%(self.index,self.remself.buffer+=bytes.decode(self.conn.recv(1024)ifself.buffer.find('rnrn')!=-1:header,data=self.buffer.splitrnrn',1)forlineinheader.split('r'n")1:key,value=line.split"",1)headerskey=valueheaderS_ocation"=("ws:/%s%s
20、"%(headers"Host",self.pathkey=headers'Sec-WebSocket-Keytoken=b64encode(hashlib.sha1(str.encode(str(key+self.GUID).digest()157.158.159. handshake=HTTP/1.1101SwitchingProtocolsrn"160. "Upgrade:websocketrn"161. "Connection:Upgradern"162. "Sec-WebSocket-A
21、ccept:"+bytes.decode(token)+rn"163. "WebSocket-Origin:"+str(headers"Origin")+"rn"164. "WebSocket-Location:"+str(headers"Location")+"rnrn"69.f.remote) 85.186
22、.90.ode191.192.193. me() 194.self.conn.send(str.encode(str(handshake)self.handshaken=Trueprint(Socket%sHandshakenwith%ssuccess%(self.index,selsendMessage(Welcome,'++'!')self.buffer_utf8=""g_code_length=0elseglobalg_code_lengthglobalg_header_lengthmm=self.c
23、onn.recv(128)iflen(mm)<=0:continueifg_code_length=0:get_datalength(mm)#接受而長度self.length_buffer=self.length_buffer+len(mm)self.buffer=self.buffer+mmifself.length_buffer-g_header_length<g_code_length:continueelse:self.buffer_utf8=parse_data(self.buffer)#utf8msg_unicode=str(self.buffer_utf8).deco
24、deutf-8','ignore')#unicifmsg_unicode=quit':print(u'Socket%sLogout!'%(self.index)nowTime=time.strftimeC%H:%M:%S',time.localtime(time.tisendMessage(%s%ssay:%s'%(nowTime,self.remote,+' Logout') 98.199.deleteconnection(str(self.index)self.con
25、n.close()break#i!出線程else#print(u'Socket%sGotmsg:%sfrom%s!'%(self.index,msg_unicode,self.remote)200.me() 201._unicode) 202.203.nowTime=time.strftime(U%H:%M:%S',time.localtime(time.tisendMessage(%s%ssay:%s'%(nowTime,self.remote,msg#重置buffer和bufferlengthself.bufferutf8=""204.
26、self.buffer=""205. g_code_length=0206. self.length_buffer=0207. self.buffer=""208.209.210. classWebSocketServer(object):211. def_init_(self):212. self.socket=None213. defbegin(self):214. print('WebSocketServerStart!)215. self.socket=socket.socket(socket.AF_INET,socket.SOCK_ST
27、REAM)216. self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)217. self.socket.bind("",12345)218. self.socket.listen(50)219.220.221. globalconnectionlist222.223.224. i=0225. whileTrue:226. connection,address=self.socket.accept()227.228.229. username=address0230. newSock
28、et=WebSocket(connection,i,username,address)231. newSocket.start()#開始線程,執(zhí)行run函數(shù)232. connectionlistfconnection+str(i)=connection233. i=i+1234.235.236. if_name_="_main_":237. server=WebSocketServer()238. server.begin()客戶端測試了chrome37,firefox35htmlviewplaincopyC1. <!DOCTYPEhtml>2. <htm
29、l>3. <head>.7.<title>WebSocket</title><style>html,bodyfont:normal0.9emarial,helvetica;#logwidth:440px;height:200px;border:1pxsolid#7F9DB9;overflow:auto;#msgwidth:330px;</style><script>varsocket;functioninit()varhost="ws:/:12345/"trysocket=newWebSocket(host);socket.onopen=function(msg)log('Connected');socket.onmessage=function(msg)log(msg.data);socket.onclose=function(msg)10g("LoseConnect
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- T-ZZB 1584-2023 低壓電源系統(tǒng)的電涌保護器(SPD)
- 二零二五年度專業(yè)技術師徒傳承合作合同
- 2025年度門店合作線上線下融合營銷協(xié)議
- 二零二五年度不占股份分紅權益共享協(xié)議
- 二零二五年度招商引資合同中的政府與企業(yè)合作模式創(chuàng)新
- 2025年度終止供貨協(xié)議函范文模板與簽訂程序指導
- 二零二五年度綠色建筑產(chǎn)業(yè)廠房租賃服務協(xié)議
- 二零二五年度勞動合同法未簽訂合同員工競業(yè)禁止協(xié)議
- 二零二五年度物業(yè)安全管理人員勞動合同范本
- 二零二五年度消防安全設施設備安全評估與整改服務合同
- 醛固酮增多癥與原發(fā)性醛固酮增多癥概述
- 20以內破十法練習題-A4打印版
- 安全生產(chǎn)治本攻堅三年行動實施方案(2024-2026年) - 副本
- 山東省淄博市2023-2024學年高一下學期期末教學質量檢測數(shù)學試題
- 數(shù)據(jù)中心容災備份解決方案
- 七年級下冊第三單元名著導讀《駱駝祥子》公開課一等獎創(chuàng)新教學設計(公開課公開課一等獎創(chuàng)新教案及作業(yè)設計)
- 2025屆新高考生物精準復習+提高農作物產(chǎn)量
- 幾何圖形中求線段線段和面積等最值問題 中考數(shù)學
- 真太陽時調整
- TD/T 1037-2013 土地整治重大項目可行性研究報告編制規(guī)程(正式版)
- 2024年時政試題庫(奪分金卷)
評論
0/150
提交評論