当前位置:   article > 正文

Python 实现 WebSocket 通信_python websocket

python websocket

WebSocket是一种在Web应用程序中实现双向通信的协议。与传统的HTTP请求-响应模型不同,WebSocket允许服务器主动向客户端推送数据,实现实时性和互动性。

以下是WebSocket的一些关键特点:

  1. 双向通信:WebSocket提供了全双工通信,允许服务器和客户端同时发送和接收数据。相比起传统的HTTP请求-响应模型,WebSocket使得服务器可以主动推送数据给客户端,而不需要客户端首先发起请求。

  2. 持久连接:与HTTP请求不同,WebSocket连接是持久的,即一旦建立连接,它将保持打开状态,直到其中一方关闭连接或发生错误。

  3. 轻量级协议:WebSocket使用简单的消息传递协议,在传输数据时减少了额外的开销。它采用二进制帧格式或文本帧格式来发送数据。

  4. 跨域支持:WebSocket支持跨域通信,允许在不同域名或端口之间建立连接和交换数据。

WebSocket在许多场景下非常有用,特别是实时通信和实时数据更新方面。它被广泛应用于在线聊天、实时游戏、股票市场行情、协同编辑和实时协作等应用程序中。

在编程中,可以使用WebSocket API来建立WebSocket连接,并使用WebSocket的事件和方法来处理连接的打开、关闭、错误和消息等操作。常见的编程语言和框架提供了对WebSocket的支持,使得开发者可以方便地实现WebSocket功能。

实现简单通信

这段代码实现了一个简单的WebSocket客户端,通过与服务器建立连接,可以实现实时的双向通信。需要注意的是,连接的URL和端口需要根据实际情况进行修改,确保与服务器端的WebSocket服务端口一致。

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <script src="https://cdn.lyshark.com/jquery/3.5.1/jquery.min.js"></script>
  6. </head>
  7. <body>
  8. <ul id="content"></ul>
  9. <form class="form">
  10. <input type="text" placeholder="请输入发送的消息" class="message" id="message"/>
  11. <input type="button" value="连接" id="connect" class="connect"/>
  12. <input type="button" value="发送" id="send" class="connect"/>
  13. </form>
  14. <script type="text/javascript">
  15. var oUl=document.getElementById('content');
  16. var oConnect=document.getElementById('connect');
  17. var oSend=document.getElementById('send');
  18. var websocket=null;
  19. oConnect.onclick=function(){
  20. websocket=new WebSocket('ws://127.0.0.1:10083');
  21. <!--客户端链接后触发-->
  22. websocket.onopen=function(){
  23. oUl.innerHTML+="<li>客户端已连接</li>";
  24. }
  25. <!--收到消息后触发-->
  26. websocket.onmessage=function(evt){
  27. oUl.innerHTML+="<li>"+evt.data+"</li>";
  28. }
  29. <!--关闭后触发-->
  30. websocket.onclose=function(){
  31. oUl.innerHTML+="<li>客户端已断开连接</li>";
  32. };
  33. <!--出错后触发-->
  34. websocket.onerror=function(evt){
  35. oUl.innerHTML+="<li>"+evt.data+"</li>";
  36. };
  37. };
  38. oSend.onclick=function(){
  39. if(websocket){
  40. websocket.send($("#message").val())
  41. }
  42. }
  43. </script>
  44. </body>
  45. </html>

后端的main.py执行处理任务,主要处理流程集中在handler_msg函数上,如下这段代码实现了一个简单的WebSocket服务器。它使用了Python的socket和threading模块来创建服务器,并处理与客户端的握手和数据交互。

代码中的主要函数和功能包括:

  1. get_headers(data): 从请求数据中获取请求头部信息,并将其转换为字典格式。

  2. parse_payload(payload): 对接收到的数据进行解码,还原出原始消息。

  3. send_msg(conn, msg_bytes): 封装并发送数据到浏览器。

  4. recv_msg(conn): 从浏览器中接收数据,并解析出原始消息。

  5. handler_accept(sock): 建立握手流程,处理与客户端的连接和握手过程。在握手完成后,创建一个新的线程来处理与客户端的数据交互。

  6. handler_msg(connect): 处理与客户端的数据交互。通过循环不断接收客户端发送的消息,并发送一个固定的回复消息。

  7. 主函数部分:创建一个socket对象并绑定到本地主机的端口10083上,然后开始监听客户端的连接请求。当有新的连接请求时,将其分配给handler_accept()函数进行处理,并在新线程中处理与客户端的数据交互。

该代码实现了一个简单的WebSocket服务器,可以接收来自客户端的连接请求,并与客户端进行数据交互。需要注意的是,服务器绑定的IP地址和端口号可以根据实际需求进行修改。

  1. import socket,struct,hashlib,base64
  2. import threading
  3. # 获取请求头部数据,并将请求头转换为字典
  4. def get_headers(data):
  5. headers = {}
  6. data = str(data, encoding="utf-8")
  7. header, body = data.split("\r\n\r\n", 1)
  8. header_list = header.split("\r\n")
  9. for i in header_list:
  10. i_list = i.split(":", 1)
  11. if len(i_list) >= 2:
  12. headers[i_list[0]] = "".join(i_list[1::]).strip()
  13. else:
  14. i_list = i.split(" ", 1)
  15. if i_list and len(i_list) == 2:
  16. headers["method"] = i_list[0]
  17. headers["protocol"] = i_list[1]
  18. print("请求类型: {} 请求协议: {}".format(i_list[0],i_list[1]))
  19. return headers
  20. # 接收数据时的解码过程
  21. def parse_payload(payload):
  22. payload_len = payload[1] & 127
  23. if payload_len == 126:
  24. mask = payload[4:8]
  25. decoded = payload[8:]
  26. elif payload_len == 127:
  27. mask = payload[10:14]
  28. decoded = payload[14:]
  29. else:
  30. mask = payload[2:6]
  31. decoded = payload[6:]
  32. # 将所有数据全部收集起来,对所有字符串编码
  33. bytes_list = bytearray()
  34. for i in range(len(decoded)):
  35. chunk = decoded[i] ^ mask[i % 4]
  36. bytes_list.append(chunk)
  37. body = str(bytes_list, encoding='utf-8')
  38. return body
  39. # 封装并发送数据到浏览器
  40. def send_msg(conn, msg_bytes):
  41. # 接收的第一个字节都是x81不变
  42. first_byte = b"\x81"
  43. length = len(msg_bytes)
  44. if length < 126:
  45. first_byte += struct.pack("B", length)
  46. elif length <= 0xFFFF:
  47. first_byte += struct.pack("!BH", 126, length)
  48. else:
  49. first_byte += struct.pack("!BQ", 127, length)
  50. msg = first_byte + msg_bytes
  51. conn.sendall(msg)
  52. return True
  53. # 从浏览器中接收数据
  54. def recv_msg(conn):
  55. data_recv = conn.recv(8096)
  56. if data_recv[0:1] == b"\x81":
  57. data_parse = parse_payload(data_recv)
  58. return data_parse
  59. return False
  60. # 建立握手流程并创建 handler_msg 完成数据收发
  61. def handler_accept(sock):
  62. while True:
  63. conn, addr = sock.accept()
  64. data = conn.recv(8096)
  65. headers = get_headers(data)
  66. # 对请求头中的sec-websocket-key进行加密
  67. response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
  68. "Upgrade:websocket\r\n" \
  69. "Connection: Upgrade\r\n" \
  70. "Sec-WebSocket-Accept: %s\r\n" \
  71. "WebSocket-Location: ws://%s\r\n\r\n"
  72. # 加盐操作,此处是H5规范定义好的
  73. magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
  74. if headers.get('Sec-WebSocket-Key'):
  75. value = headers['Sec-WebSocket-Key'] + magic_string
  76. # 对数据进行加解密
  77. ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())
  78. response_str = response_tpl % (ac.decode('utf-8'), headers.get("Host"))
  79. # 相应握手包数据
  80. conn.sendall(bytes(response_str, encoding="utf-8"))
  81. t = threading.Thread(target=handler_msg, args=(conn, ))
  82. t.start()
  83. # 主函数,用于实现数据交互
  84. def handler_msg(connect):
  85. with connect as connect_ptr:
  86. while True:
  87. try:
  88. recv = recv_msg(connect_ptr)
  89. print("接收数据: {}".format(recv))
  90. send_msg(connect_ptr, bytes("hello lyshark", encoding="utf-8"))
  91. except Exception:
  92. exit(0)
  93. if __name__ == "__main__":
  94. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  95. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  96. sock.bind(("127.0.0.1", 10083))
  97. sock.listen(5)
  98. t = threading.Thread(target=handler_accept(sock))
  99. t.start()

绘制动态图形

如下这段代码实现了一个简单的实时CPU数据展示页面。通过WebSocket与服务器建立连接,并实时接收和展示来自服务器的CPU数据。需要注意的是,页面中WebSocket连接的IP地址和端口号需要根据实际情况进行修改,确保与服务器建立正确的连接。另外,使用ECharts库来绘制折线图需要保证页面能够正确加载ECharts的JavaScript文件。

代码中的主要部分包括:

  1. 引入ECharts库:使用<script>标签引入ECharts库的JavaScript文件,以便在页面中使用ECharts。

  2. HTML结构:在页面中创建一个<div>元素,用于显示折线图。

  3. JavaScript代码:定义了一个名为display的函数,用于初始化和更新折线图。该函数接收两个参数:时间数组和CPU数据数组。通过调用ECharts的setOption方法,配置折线图的样式和数据,并将其显示在指定的<div>元素中。

  4. WebSocket通信:创建一个WebSocket对象,与服务器建立WebSocket连接。通过监听onmessage事件,接收服务器发送的CPU数据。将接收到的数据解析为JSON格式,将时间和CPU数据分别添加到对应的数组中。当时间数组和CPU数据数组的长度达到10时,删除数组中最旧的数据,并调用display函数更新折线图。

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <script type="text/javascript" src="https://cdn.lyshark.com/echarts/5.0.0/echarts.min.js"></script>
  6. </head>
  7. <body>
  8. <center><div id="main" style="height:400px;width:90%;border:1px solid #eecc11;padding:10px;"></div></center>
  9. <script type="text/javascript" charset="UTF-8">
  10. var display = function(time,cpu) {
  11. var main = echarts.init(document.getElementById(("main")));
  12. var option = {
  13. xAxis: {
  14. type: 'category',
  15. data: time
  16. },
  17. yAxis: {
  18. type: 'value'
  19. },
  20. series: [{
  21. type: 'line',
  22. smooth:0.3,
  23. symbol: 'none',
  24. color: 'blue',
  25. smooth: true,
  26. areaStyle: {
  27. color: '#0000CD',
  28. origin: 'start',
  29. opacity: 0.5
  30. },
  31. data: cpu
  32. }]
  33. };
  34. main.setOption(option,true);
  35. };
  36. </script>
  37. <script type="text/javascript" charset="UTF-8">
  38. var ws=new WebSocket('ws://127.0.0.1:10083');
  39. var time =["","","","","","","","","",""];
  40. var cpu = [0,0,0,0,0,0,0,0,0,0];
  41. ws.onmessage=function(evt)
  42. {
  43. var recv = JSON.parse(evt.data);
  44. time.push(recv.response[0]);
  45. cpu.push(parseFloat(recv.response[1]));
  46. if(time.length >=10){
  47. time.shift();
  48. cpu.shift();
  49. console.log("时间:" + time + " --> CPU数据: " + cpu);
  50. display(time,cpu)
  51. }
  52. }
  53. </script>
  54. </body>
  55. </html>

后台部分我们主要代码不需要动,只需要修改handler_msg处理流程即可,代码能够接受客户端的连接请求,并定时发送CPU数据给客户端。需要注意的是,代码中的sock.bind(("127.0.0.1", 10083))绑定的是本地地址和指定的端口号,需要根据实际情况进行修改。另外,需要确保在服务器环境中安装了psutil库,以便获取CPU使用率数据。

  1. import socket,struct,hashlib,base64
  2. import threading
  3. # 获取请求头部数据,并将请求头转换为字典
  4. def get_headers(data):
  5. headers = {}
  6. data = str(data, encoding="utf-8")
  7. header, body = data.split("\r\n\r\n", 1)
  8. header_list = header.split("\r\n")
  9. for i in header_list:
  10. i_list = i.split(":", 1)
  11. if len(i_list) >= 2:
  12. headers[i_list[0]] = "".join(i_list[1::]).strip()
  13. else:
  14. i_list = i.split(" ", 1)
  15. if i_list and len(i_list) == 2:
  16. headers["method"] = i_list[0]
  17. headers["protocol"] = i_list[1]
  18. print("请求类型: {} 请求协议: {}".format(i_list[0],i_list[1]))
  19. return headers
  20. # 接收数据时的解码过程
  21. def parse_payload(payload):
  22. payload_len = payload[1] & 127
  23. if payload_len == 126:
  24. mask = payload[4:8]
  25. decoded = payload[8:]
  26. elif payload_len == 127:
  27. mask = payload[10:14]
  28. decoded = payload[14:]
  29. else:
  30. mask = payload[2:6]
  31. decoded = payload[6:]
  32. # 将所有数据全部收集起来,对所有字符串编码
  33. bytes_list = bytearray()
  34. for i in range(len(decoded)):
  35. chunk = decoded[i] ^ mask[i % 4]
  36. bytes_list.append(chunk)
  37. body = str(bytes_list, encoding='utf-8')
  38. return body
  39. # 封装并发送数据到浏览器
  40. def send_msg(conn, msg_bytes):
  41. # 接收的第一个字节都是x81不变
  42. first_byte = b"\x81"
  43. length = len(msg_bytes)
  44. if length < 126:
  45. first_byte += struct.pack("B", length)
  46. elif length <= 0xFFFF:
  47. first_byte += struct.pack("!BH", 126, length)
  48. else:
  49. first_byte += struct.pack("!BQ", 127, length)
  50. msg = first_byte + msg_bytes
  51. conn.sendall(msg)
  52. return True
  53. # 从浏览器中接收数据
  54. def recv_msg(conn):
  55. data_recv = conn.recv(8096)
  56. if data_recv[0:1] == b"\x81":
  57. data_parse = parse_payload(data_recv)
  58. return data_parse
  59. return False
  60. # 建立握手流程并创建 handler_msg 完成数据收发
  61. def handler_accept(sock):
  62. while True:
  63. conn, addr = sock.accept()
  64. data = conn.recv(8096)
  65. headers = get_headers(data)
  66. # 对请求头中的sec-websocket-key进行加密
  67. response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
  68. "Upgrade:websocket\r\n" \
  69. "Connection: Upgrade\r\n" \
  70. "Sec-WebSocket-Accept: %s\r\n" \
  71. "WebSocket-Location: ws://%s\r\n\r\n"
  72. # 加盐操作,此处是H5规范定义好的
  73. magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
  74. if headers.get('Sec-WebSocket-Key'):
  75. value = headers['Sec-WebSocket-Key'] + magic_string
  76. # 对数据进行加解密
  77. ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())
  78. response_str = response_tpl % (ac.decode('utf-8'), headers.get("Host"))
  79. # 相应握手包数据
  80. conn.sendall(bytes(response_str, encoding="utf-8"))
  81. t = threading.Thread(target=handler_msg, args=(conn, ))
  82. t.start()
  83. # 主函数,用于实现数据交互
  84. def handler_msg(conn):
  85. with conn as c:
  86. while True:
  87. try:
  88. times = time.strftime("%M:%S", time.localtime())
  89. data = psutil.cpu_percent(interval=None, percpu=True)
  90. print("处理时间: {} --> 处理负载: {}".format(times, data))
  91. send_msg(c, bytes(json.dumps({"response": [times, data]}), encoding="utf-8"))
  92. time.sleep(60)
  93. except Exception:
  94. exit(0)
  95. if __name__ == "__main__":
  96. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  97. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  98. sock.bind(("127.0.0.1", 10083))
  99. sock.listen(5)
  100. t = threading.Thread(target=handler_accept(sock))
  101. t.start()

实现动态交互

新建index.html写入如下代码,这段代码实现了一个Web页面,包含了一个可交互的终端,可以通过输入地址范围和执行命令来批量执行命令,并实时显示执行结果。需要注意的是,代码中的WebSocket连接地址和端口号需要根据实际情况进行修改,确保与后端WebSocket服务器的地址和端口号一致。

代码中的主要部分包括:

  1. 引入CSS和JavaScript库:页面引入了xterm.cssxterm.js来加载和渲染终端的外观样式和功能,同时还引入了jQuery库用于简化DOM操作。

  2. 创建终端实例:通过new Terminal()创建了一个终端实例term,设置了终端的行数、列数、换行符转换、光标闪烁等属性。

  3. WebSocket连接:通过new WebSocket()创建了一个WebSocket实例sock,并指定了与后端的WebSocket服务器的地址和端口号。

  4. 终端打开和消息接收:在sock.onopen回调函数中,调用term.open()打开终端,并在控制台输出WebSocket连接成功的消息。在sock.onmessage回调函数中,解析接收到的JSON数据,提取地址和状态信息,并将其显示在终端中。

  5. 执行命令:通过$('#send_message').click()事件处理函数,获取输入框中的地址和命令信息,将其封装成JSON格式,并通过WebSocket发送给后端。

  1. <html>
  2. <head>
  3. <meta charSet="utf-8">
  4. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  5. <link rel="stylesheet" href="https://cdn.lyshark.com/xterm/xterm.css"/>
  6. <script src="https://cdn.lyshark.com/xterm/xterm.js"></script>
  7. <script src="https://cdn.lyshark.com/jquery/3.5.1/jquery.min.js" type="text/javascript"></script>
  8. </head>
  9. <body>
  10. <div id="terminal"></div>
  11. <input type="text" id="address" placeholder="主机范围 127.0.0.1-100" style="width:200px;height:40px"/>
  12. <input type="text" id="command" placeholder="执行命令 ls -lh " style="width:400px;height:40px"/>
  13. <input type="button" id="send_message" value="批量执行">
  14. <!--实现格式化字符串-->
  15. <script type="text/javascript">
  16. $.format = function(source, params)
  17. {
  18. if (arguments.length == 1) return function()
  19. {
  20. var args = $.makeArray(arguments);
  21. args.unshift(source);
  22. return $.format.apply(this, args);
  23. };
  24. if (arguments.length > 2 && params.constructor != Array)
  25. {
  26. params = $.makeArray(arguments).slice(1);
  27. }
  28. if (params.constructor != Array)
  29. {
  30. params = [params];
  31. }
  32. $.each(params,
  33. function(i, n)
  34. {
  35. source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
  36. });
  37. return source;
  38. };
  39. </script>
  40. <!--打开终端,并开始执行命令-->
  41. <script type="text/javascript">
  42. $(function(){
  43. var window_width = $(window).width()-200;
  44. var window_height = $(window).height()-300;
  45. var term = new Terminal(
  46. {
  47. cols: Math.floor(window_width/9),
  48. rows: Math.floor(window_height/20),
  49. convertEol: true,
  50. cursorBlink:false,
  51. });
  52. var sock = new WebSocket("ws://127.0.0.1:10083");
  53. sock.onopen = function () {
  54. term.open(document.getElementById('terminal'));
  55. console.log('WebSocket Open');
  56. };
  57. sock.onmessage = function (recv) {
  58. var data = JSON.parse(recv.data);
  59. console.log(data['addr'] + ' -- ' + data['status']);
  60. var temp = "\x1B[1;3;35m 地址:[ {0} ] \x1B[0m --> \x1B[1;3;33m 状态:[ {1} ] \x1B[0m";
  61. var string = $.format(temp, data['addr'],data['status']);
  62. term.writeln(string);
  63. };
  64. $('#send_message').click(function () {
  65. var message ={"address":null,"command":null};
  66. message['address'] = $("#address").val();
  67. message['command'] = $("#command").val();
  68. var send_data = JSON.stringify(message);
  69. window.sock.send(send_data);
  70. });
  71. window.sock = sock;
  72. });
  73. </script>

后端代码如下所示,其中核心代码handler_msg(conn),用于处理接收到的消息,解析地址范围,并针对每个地址执行命令。执行结果会通过WebSocket发送回客户端,并在后台打印出对应的主机和执行的命令。需要注意的是,代码中的函数recv_msg()send_msg()没有提供具体的实现,你需要根据具体的需求自行实现这两个函数。

  1. CalculationIP(Addr_Count)函数用于解析地址范围,并生成对应的IP地址列表。参数Addr_Count是一个地址范围字符串,如"127.0.0.1-100"。函数首先根据"-"符号将地址范围字符串分割为起始IP和结束IP的两部分。然后根据起始IP生成IP地址的前三个部分,即IP地址的头部。接着根据起始IP和结束IP的范围,循环生成完整的IP地址,并将其添加到结果列表中。最后返回生成的IP地址列表。

  2. handler_msg(conn)函数是一个无限循环,用于处理消息并执行命令。在循环中,首先使用eval(recv_msg(c))函数接收并解析JSON格式的消息数据。然后从消息中获取地址和命令信息。接下来调用CalculationIP()函数生成地址列表。然后遍历地址列表,对每个地址执行命令,并将执行结果发送回客户端。执行过程中,会打印出对应的主机和执行的命令。在每次执行完命令后,程序会暂停1秒钟。如果在执行过程中发生异常,程序会退出。

  1. import socket,struct,hashlib,base64
  2. import threading,psutil
  3. # 获取请求头部数据,并将请求头转换为字典
  4. def get_headers(data):
  5. headers = {}
  6. data = str(data, encoding="utf-8")
  7. header, body = data.split("\r\n\r\n", 1)
  8. header_list = header.split("\r\n")
  9. for i in header_list:
  10. i_list = i.split(":", 1)
  11. if len(i_list) >= 2:
  12. headers[i_list[0]] = "".join(i_list[1::]).strip()
  13. else:
  14. i_list = i.split(" ", 1)
  15. if i_list and len(i_list) == 2:
  16. headers["method"] = i_list[0]
  17. headers["protocol"] = i_list[1]
  18. print("请求类型: {} 请求协议: {}".format(i_list[0],i_list[1]))
  19. return headers
  20. # 接收数据时的解码过程
  21. def parse_payload(payload):
  22. payload_len = payload[1] & 127
  23. if payload_len == 126:
  24. mask = payload[4:8]
  25. decoded = payload[8:]
  26. elif payload_len == 127:
  27. mask = payload[10:14]
  28. decoded = payload[14:]
  29. else:
  30. mask = payload[2:6]
  31. decoded = payload[6:]
  32. # 将所有数据全部收集起来,对所有字符串编码
  33. bytes_list = bytearray()
  34. for i in range(len(decoded)):
  35. chunk = decoded[i] ^ mask[i % 4]
  36. bytes_list.append(chunk)
  37. body = str(bytes_list, encoding='utf-8')
  38. return body
  39. # 封装并发送数据到浏览器
  40. def send_msg(conn, msg_bytes):
  41. # 接收的第一个字节都是x81不变
  42. first_byte = b"\x81"
  43. length = len(msg_bytes)
  44. if length < 126:
  45. first_byte += struct.pack("B", length)
  46. elif length <= 0xFFFF:
  47. first_byte += struct.pack("!BH", 126, length)
  48. else:
  49. first_byte += struct.pack("!BQ", 127, length)
  50. msg = first_byte + msg_bytes
  51. conn.sendall(msg)
  52. return True
  53. # 从浏览器中接收数据
  54. def recv_msg(conn):
  55. data_recv = conn.recv(8096)
  56. if data_recv[0:1] == b"\x81":
  57. data_parse = parse_payload(data_recv)
  58. return data_parse
  59. return False
  60. # 建立握手流程并创建 handler_msg 完成数据收发
  61. def handler_accept(sock):
  62. while True:
  63. conn, addr = sock.accept()
  64. data = conn.recv(8096)
  65. headers = get_headers(data)
  66. # 对请求头中的sec-websocket-key进行加密
  67. response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
  68. "Upgrade:websocket\r\n" \
  69. "Connection: Upgrade\r\n" \
  70. "Sec-WebSocket-Accept: %s\r\n" \
  71. "WebSocket-Location: ws://%s\r\n\r\n"
  72. # 加盐操作,此处是H5规范定义好的
  73. magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
  74. if headers.get('Sec-WebSocket-Key'):
  75. value = headers['Sec-WebSocket-Key'] + magic_string
  76. # 对数据进行加解密
  77. ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())
  78. response_str = response_tpl % (ac.decode('utf-8'), headers.get("Host"))
  79. # 相应握手包数据
  80. conn.sendall(bytes(response_str, encoding="utf-8"))
  81. t = threading.Thread(target=handler_msg, args=(conn, ))
  82. t.start()
  83. def CalculationIP(Addr_Count):
  84. ret = []
  85. try:
  86. IP_Start = str(Addr_Count.split("-")[0]).split(".")
  87. IP_Heads = str(IP_Start[0] + "." + IP_Start[1] + "." + IP_Start[2] +".")
  88. IP_Start_Range = int(Addr_Count.split(".")[3].split("-")[0])
  89. IP_End_Range = int(Addr_Count.split("-")[1])
  90. for item in range(IP_Start_Range,IP_End_Range+1):
  91. ret.append(IP_Heads+str(item))
  92. return ret
  93. except Exception:
  94. return 0
  95. def handler_msg(conn):
  96. with conn as c:
  97. while True:
  98. try:
  99. ref_json = eval(recv_msg(c))
  100. address = ref_json.get("address")
  101. command = ref_json.get("command")
  102. address_list = CalculationIP(address)
  103. for ip in address_list:
  104. response = {'addr': ip, 'status': 'success'}
  105. print("对主机: {} --> 执行: {}".format(ip,command))
  106. send_msg(c, bytes(json.dumps(response) , encoding="utf-8"))
  107. time.sleep(1)
  108. except Exception:
  109. exit(0)
  110. if __name__ == "__main__":
  111. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  112. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  113. sock.bind(("127.0.0.1", 10083))
  114. sock.listen(5)
  115. t = threading.Thread(target=handler_accept(sock))
  116. t.start()
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/85383
推荐阅读
相关标签
  

闽ICP备14008679号