RPC 笔记(06)— socket 通信(多线程服务器)

news/2025/2/15 21:37:40/

1. 客户端代码

import json
import time
import struct
import socketdef send_request(sock_obj, method, parameter):request = json.dumps({"client": method, "params": parameter})       # 请求消息体length_prefix = struct.pack("I", len(request))                      # 请求长度前缀print("request is {}".format(str.encode(request)))sock_obj.sendall(length_prefix)# sock.sendall(request) python2sock_obj.sendall(str.encode(request))   # python3def receive_response(sock_obj):length_prefix = sock_obj.recv(4)                # 响应长度前缀length, = struct.unpack("I", length_prefix)# print("length is {}".format(length))body = sock_obj.recv(length)                    # 响应消息体res = json.loads(body)return res                                      # 返回响应if __name__ == '__main__':s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(("localhost", 8080))for i in range(10):send_request(s, "func1", "I am {} message".format(i))response = receive_response(s)print("response is {}".format(response))time.sleep(1)s.close()

2. 服务端代码

import json
import struct
import socket
import threadingdef handle_conn(conn, ip, handlers):print("{} connect ...".format(ip))# 循环读写while True:length_prefix = conn.recv(4)  # 请求长度前缀if not length_prefix:         # 连接关闭了conn.close()print("{} close ...".format(ip))break  # 退出循环,处理下一个连接length, = struct.unpack("I", length_prefix)body = conn.recv(length)  # 请求消息体request = json.loads(body)client_method = request['client']client_parameter = request['params']print("client request method is {}, params is {}".format(client_method, client_parameter))handler = handlers[client_method]  # 查找请求处理器handler(conn, client_parameter)  # 处理请求def process_request(sock, handlers):while True:conn, host_ip = sock.accept()  # 接收连接handle_conn(conn, host_ip, handlers)  # 处理连接def func1(conn, params):res = json.dumps({"response": "OK", "result": params})  # 响应消息体length_prefix = struct.pack("I", len(res))  # 响应长度前缀conn.sendall(length_prefix)# conn.sendall(response)  # python2conn.sendall(str.encode(res))  # python3def main():s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建一个 TCP 套接字s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 打开 reuse addr 选项s.bind(("localhost", 8080))  # 绑定端口s.listen(1)  # 监听客户端连接handlers = {"func1": func1    # 注册请求处理器}# process_request(s, handlers)  # 进入服务循环threads = []thread_nums = 3for i in range(thread_nums):t = threading.Thread(target=process_request, args=(s, handlers))threads.append(t)for i in range(thread_nums):threads[i].start()for i in range(thread_nums):threads[i].join()if __name__ == '__main__':main()

服务端开了 3 个线程用于处理客户端请求,此时如果客户端数量小于等于 3时,服务端会并行处理,如果客户端数量大于 3 服务端则会阻塞,直到有之前连接的客户端断开,才会继续处理。


http://www.ppmy.cn/news/603124.html

相关文章

opencv C++ 读取视频中的光斑是否在移动(图片存储在指定文件见下,光斑坐标存在TXT文本中)

读取视频中的光斑是否在移动(图片存储在指定文件见下,光斑坐标存在TXT文本中) /* 功能:1.判断视频中的光斑是否在动2.每一帧图像保存在指定文件夹下3.将获得的坐标保存到TXT文件 附加优化功能:1.截取幕布区域,进行处理(提高准确性、提高效率) */#include <opencv2/…

RPC 笔记(07)— socket 通信(多进程服务器)

上节我们完成了一个简单的多线程服务器&#xff0c;可以并发处理多个客户端连接。但是 Python 由于全局解释器锁 GIL 的存在&#xff0c;致使多个线程只能占满一个 CPU 核心&#xff0c;多线程并不能充分利用多核的优势。所以多数 Python 服务器推荐使用多进程模型。 ​ 服务端…

RPC 笔记(08)— socket 通信(多进程多线程服务器)

在上一节中如果并行的客户端连接数超过了默认开启进程的数量&#xff0c;那么后来的客户端请求将会阻塞&#xff0c;为了不阻塞新的客户端&#xff0c;我们可以将进程的单线程改成多线程即可。 ​ 服务端代码&#xff1a; import json import struct import socket import th…

Pyinstaller 打包 torch 后执行失败 OSError: could not get source code

1. 问题现象 系统环境 Python 3.6.9torch 1.2.0torchvision 0.4.0Pyinstaller 4.5.1 Pyinstaller 打包 torch 后执行失败 OSError: could not get source code 。 Traceback (most recent call last):File "main.py", line 29, in <module>File "<…

ERROR: Failed compiling the bootloader. Please compile manually and rerun setup.py

1. 问题现象 在使用 pip 安装 pyinstaller 时&#xff0c;有如下错误 $ sudo pip3 install pyinstaller4.5.1 -i https://pypi.douban.com/simple/Collecting pyinstaller4.5.1Downloading https://pypi.doubanio.com/packages/a9/d9/9fdfb0ac2354d059e466d562689dbe53a23…

pip 无法卸载 pillow 解决方案 Not uninstalling pillow at /usr/lib/python3/dist-packages

1. 问题现象 使用 pip 卸载 pillow 时无法卸载&#xff0c;报如下错误&#xff1a; $ sudo pip3 uninstall pillow Not uninstalling pillow at /usr/lib/python3/dist-packages, outside environment /usr2. 解决方法 sudo apt remove python3-pil或者 sudo apt remove…

使用 Go module 后 VScode 智能提示不生效解决方案

关闭 Use Language Server 如果你对这个选项有打钩先取消&#xff0c;然后重启 vscode 。 安装 gocode go install github.com/stamblerre/gocodelatest参考 https://www.icode9.com/content-4-719446.html https://blog.csdn.net/richard_m_yang/article/details/100516891…

Docker 常见问题 — 配置国内镜像源、备份本机所有镜像文件、批量清理临时镜像文件、删除所有本地镜像、镜像默认存放路径、

1. 配置国内镜像源 由 Docker 官方提供的国内镜像源&#xff1a; registry.docker-cn.com在 Linux 环境下&#xff0c;我们可以通过修改 /etc/docker/daemon.json ( 如果文件不存在&#xff0c;直接创建它 ) 这个 Docker 服务的配置文件达到效果。 {"registry-mirrors&…