python與html5搭建聊天室_html5 websocket 新版協議聊天室 服務端(python版)

網上找了很多代碼都是舊版協議的,研究了很久終于弄清楚了 現在發個用新版協議寫的服務端代碼出來(這個代碼是從網上舊版協議改過來的)

最要就是握手協議和發送接受字符的方式變了

# incoding=utf-8

import socket

import struct

import hashlib

import threading,random

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

connectionlist = {}

def sendMessage(message):

global connectionlist

for connection in connectionlist.values():

print connection

bstr = send_data(message)

print bstr

b = connection.send(bstr)

def deleteconnection(item):

global connectionlist

del connectionlist['connection'+item]

#接收客戶端發送過來的消息,并且解包

def RecvData(nNum,client):

try:

pData = client.recv(nNum)

if not len(pData):

return False

except:

return False

else:

code_length = ord(pData[1]) & 127

if code_length == 126:

masks = pData[4:8]

data = pData[8:]

elif code_length == 127:

masks = pData[10:14]

data = pData[14:]

else:

masks = pData[2:6]

data = pData[6:]

raw_str = ""

i = 0

for d in data:

raw_str += chr(ord(d) ^ ord(masks[i%4]))

i += 1

return raw_str

#打包發送數據給客戶端

def SendData(pData,client):

if(pData == False):

return False

else:

pData = str(pData)

token = "\x81"

length = len(pData)

if length < 126:

token += struct.pack("B", length)

elif length <= 0xFFFF:

token += struct.pack("!BH", 126, length)

else:

token += struct.pack("!BQ", 127, length)

pData = '%s%s' % (token,pData)

client.send(pData)

return True

def send_data(raw_str):

back_str = []

back_str.append('\x81')

data_length = len(raw_str)

if data_length < 125:

back_str.append(chr(data_length))

else:

back_str.append(chr(126))

back_str.append(chr(data_length >> 8))

back_str.append(chr(data_length & 0xFF))

back_str = "".join(back_str) + raw_str

return back_str

class WebSocket(threading.Thread):

def __init__(self,conn,index,name,remote, path="/"):

threading.Thread.__init__(self)

self.conn = conn

self.index = index

self.name = name

self.remote = remote

self.path = path

self.buffer = ""

def run(self):

print 'Socket%s Start!' % self.index

headers = {}

self.handshaken = False

while True:

if self.handshaken == False:

print 'Socket%s Start Handshaken with %s!' % (self.index,self.remote)

self.buffer += self.conn.recv(1024)

if self.buffer.find('\r\n\r\n') != -1:

header, data = self.buffer.split('\r\n\r\n', 1)

for line in header.split("\r\n")[1:]:

key, value = line.split(": ", 1)

headers[key] = value

print 'header:-->'+header

headers["Location"] = "ws://%s%s" %(headers["Host"], self.path)

self.buffer = data[8:]

key = headers["Sec-WebSocket-Key"]

token = self.generate_token(key)

handshake = '\

HTTP/1.1 101 Web Socket Protocol Handshake\r\n\

Upgrade: webSocket\r\n\

Connection: Upgrade\r\n\

Sec-WebSocket-Accept:%s\r\n\

Sec-WebSocket-Origin: %s\r\n\

Sec-WebSocket-Location: %s\r\n\r\n\

' %(token,headers['Origin'], headers['Location'])

print handshake

num = self.conn.send(handshake)

print str(num)

self.handshaken = True

print 'Socket%s Handshaken with %s success!' % (self.index,self.remote)

#self.conn.send('\x00'+'Welcome'+'\xFF'+'\n')

bstr = send_data("Welcome")

print bstr

self.conn.send(bstr)

#SendData('\x00'+'Welcome'+'\xFF',self.conn)

#sendMessage('Welcome, '+self.name+' !')

else:

self.buffer = RecvData(8196,self.conn)

if self.buffer:

print 'rec:'+self.buffer

if self.buffer:

#s = self.buffer.split("\xFF")[0][1:]

s = self.buffer

if s=='quit':

print 'Socket%s Logout!' % (self.index)

sendMessage(self.name+' Logout')

deleteconnection(str(self.index))

self.conn.close()

break

else:

print 'Socket%s Got msg:%s from %s!' % (self.index,s,self.remote)

sendMessage(self.name+':'+s)

self.buffer = ""

def generate_token(self, key):

import base64

nkey=key+'258EAFA5-E914-47DA-95CA-C5AB0DC85B11'

nkey=base64.b64encode(hashlib.sha1(nkey).digest())

return nkey

class WebSocketServer(object):

def __init__(self):

self.socket = None

def begin(self):

print 'WebSocketServer Start!'

self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.socket.bind(("192.168.1.210",1234))

self.socket.listen(50)

global connectionlist

i=0

while True:

connection, address = self.socket.accept()

username=address[0]

newSocket = WebSocket(connection,i,username,address)

newSocket.start()

connectionlist['connection'+str(i)]=connection

i = i + 1

if __name__ == "__main__":

server = WebSocketServer()

server.begin()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530154.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530154.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530154.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql數據庫開發筆記_MySQL數據庫生成數據庫說明文檔

在半年多前為一個MySQL數據庫生成過數據庫說明文檔&#xff0c;今天要重新生成一份&#xff0c;但是發現完全不記得當時是怎么生成的&#xff0c;只能在網上搜索重來一遍&#xff0c;所以今天特意把這個過程記錄一下。一、安裝使用MySQL數據庫表結構導出器DBExportDoc V1.0 For…

java 字符串緩沖區_詳解Java中字符串緩沖區StringBuffer類的使用

StringBuffer 是一個線程安全的可變的字符序列。它繼承于AbstractStringBuilder&#xff0c;實現了CharSequence接口。StringBuilder 也是繼承于AbstractStringBuilder的子類&#xff1b;但是&#xff0c;StringBuilder和StringBuffer不同&#xff0c;前者是非線程安全的&#…

rabbitmq java文檔_RabbitMQ文檔翻譯——Hello World!(上)

文章主要翻譯自RabbitMQ官方文檔&#xff0c;主要是為了練習英語翻譯&#xff0c;順便學習一下RabbitMQ&#x1f636;其中也記錄了一些爬過的坑IntroductionRabbitMQ is a message broker. The principal idea is pretty simple: it accepts and forwards messages. You can th…

java string 包含http_Java中使用HttpPost上傳文件以及HttpGet進行API請求(包含HttpPost上傳文件)...

一、HttpPost上傳文件public static String getSuffix(final MultipartFile file){if(file null || file.getSize() 0){return null;}String fileName file.getOriginalFilename();return fileName.substring(fileName.lastIndexOf(".")1);}public static JSONObj…

java倒計時跳出窗口_java倒計時彈出框

直接使用java語言寫出一個運行時的彈出框倒計時&#xff1a;package test.dagong.testDecreaseDate;import java.awt.Container;import java.awt.FlowLayout;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.sw…

jpa mysql存儲過程_Jpa調用存儲過程及參數

public List findAllEntityListBySearch(Long inputInfoId, int flag) throws Exception {List infoviewListnew ArrayList<>();EntityManager em emf.createEntityManager();try {StoredProcedureQuery storedProcedure em.createStoredProcedureQuery("存儲名稱&…

python從mongodb里取出數據進行可視化_python3 mongoDB數據庫的安裝配置與可視化

python3 mongoDB數據庫的安裝配置與可視化。前天說是要學習如何使用mongoDB的鏈接與安裝。安裝環境&#xff1a; wind10 還是盜版的 磁盤分析&#xff1a;只有一個C盤&#xff0c;步驟&#xff1a;1 . 下載這里下載了對應的msi文件&#xff0c;貌似.zip文件沒有了2 我默認把mon…

idea 注入mapper報錯報紅的幾種解決方案

文章目錄 前言方法1&#xff1a;為 Autowired 注解設置required false方法2&#xff1a;用 Resource 替換 Autowired方法3&#xff1a;在Mapper接口上加上Repository注解方法4&#xff1a;用Lombok方法5&#xff1a;把IDEA的警告關閉掉方法6&#xff1a;不用管他 前言 相信大…

java 調用對象的方法_JAVA調用對象方法的執行過程

JAVA調用對象方法的執行過程&#xff1a;①.編譯器查看對象的聲明類型和方法名。假設調用x.f(parameter), 且隱式參數x聲明為C類型的對象&#xff0c;有可能在C對象中存在多個參數類型和參數個數不同的f的方法{例如&#xff1a;f(int)、f(int,String)和f(String)}&#xff0c;…

java類默認權限_Java 訪問權限控制以及類初始化順序

一. Package在一個項目中&#xff0c;不可以有相同的兩個包名package語句必須是文件中除注釋外第一句程序代碼&#xff0c;否則不能通過編譯。二. Java訪問權限概述類成員&#xff1a;對于一個類&#xff0c;其成員(包括成員變量和成員方法)能否被其他類所訪問&#xff0c;取決…

java http頭 字符串轉日期_springboot~DTO字符字段與日期字段的轉換問題

不會自動轉換string與date主要是這個意思&#xff0c;前端提交的JSON里&#xff0c;日期是一個字符串&#xff0c;而對應后端的實體里&#xff0c;它是一個Date的日期&#xff0c;這兩個在默認情況下是不能自動轉換的&#xff0c;我們先看一下實體實體public class UserDTO {pr…

java super extends_Java繼承和super的用法

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓繼承的關鍵字:extends格式如下: class 子類名 extends父類名{...}例如學生是繼承人類這一父類的.class student extends person{...}如果一個類的聲明沒有使用關鍵字extends,則這個類默認是繼承Object類的.Object是所有類的父類.Ob…

比較abc大小的java_比較abc大小java

比較abc大小java[2021-02-09 04:04:20] 簡介:php去除nbsp的方法&#xff1a;首先創建一個PHP代碼示例文件&#xff1b;然后通過“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp即可。推薦&#xff1a;《PH…

海天食品的java開發工作如何_再三個月就秋招了,我想找一份java開發工作,現在應該怎么準備一下?...

在找工作之前&#xff0c;大家都要做一些準備工作&#xff0c;java開發也是如此掌握核心JavaSE首先&#xff0c;從核心Java(JavaSE)開始學習&#xff0c;盡可能地掌握它。你應該了解和掌握一些基本概念&#xff0c;如循環&#xff0c;數組&#xff0c;運算符等等。此外&#xf…

java udp簡單聊天程序_Java基于UDP協議實現簡單的聊天室程序

最近比較閑&#xff0c;一直在抽空回顧一些java方面的技術應用。今天沒什么事做&#xff0c;基于udp協議&#xff0c;寫了一個非常簡單的聊天室程序。現在的工作&#xff0c;很少用到socket&#xff0c;也算是對java網絡編程方面的一個簡單回憶。先看一下效果&#xff1a;實現的…

java9 反應編程_Java9第四篇-Reactive Stream API響應式編程

file我計劃在后續的一段時間內&#xff0c;寫一系列關于java 9的文章&#xff0c;雖然java 9 不像Java 8或者Java 11那樣的核心java版本&#xff0c;但是還是有很多的特性值得關注。期待您能關注我&#xff0c;我將把java 9 寫成一系列的文章&#xff0c;大概十篇左右。Java 9的…

bb10系統支持java嗎_黑莓BB10怎么樣 BlackBerry 10系統好用嗎?

曾幾何時黑莓Blackberry OS是一款十分受用戶歡迎的手機系統&#xff0c;不過隨著手機系統市場已經被蘋果iOS、谷歌安卓、微軟Windows Phone三分天下&#xff0c;致使曾經的黑莓帝國逐漸淪陷&#xff0c;體驗和性能都已經明顯跟不上iOS與安卓等系統的腳步了&#xff0c;也因為如…

java中興參與實參相同_中興通訊_傳輸SDH試題(含答案)

中興傳輸SDH試題一、單項選擇題(每小題2分&#xff0c;共30分)1、在SDH系統中, RSOH指(A)。A.再生段開銷B.復用段開銷C.再生段通道開銷D.復用段通道開銷2.、同步數字體系SDH具有(A)幀結構。A.塊狀B.串行C.鏈形D.三維3、管理指針單元的作用是(A)。A、用來指示信息凈負荷的第一個…

php 正則提取url,php 正則表達式提取網頁超級鏈接url的函數

function match_links($document) {preg_match_all("]))[^>]*>?(.*?)isx",$document,$links);while(list($key,$val) each($links[2])) {if(!empty($val))$match[link][] $val;}while(list($key,$val) each($links[3])) {if(!empty($val))$match[link][] …

php array colum,php5.5新數組函數array_column使用

array_column 用于獲取二維數組中的元素(PHP 5 > 5.5.0)&#xff0c;但我們有時候需要在低版本中使用&#xff0c;那么就可以使用下面的代碼即可PHP5.5發布了&#xff0c;其中增加了一個新的數組函數array_column&#xff0c;感覺不錯的&#xff01;但是低版本PHP要使用&…