多线程实现socket通信服务器端代码

import socket
import threading class MyServer(object):
def __init__(self):
# 初始化socket
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置服务器IP地址
host = '192.168.152.1'
# 设置服务器端口号
port = 4321
# 绑定IP地址和端口
self.server.bind((host, port))
# 设置最大监听数
self.server.listen(5)
# 设置一个字典,用来保存每一个客户端的连接和身份信息
self.socket_mapping = {}
# 设置接收的最大字节数
self.maxSize = 1024 def run(self):
while True:
socket, addr = self.server.accept()
# 发送信息,提示客户端已成功连接
socket.send('success!'.encode('utf-8'))
# 将客户端socket等信息存入字典
self.socket_mapping[socket] = addr
# 创建线程,负责获取键盘输入并发送给客户端
threading.Thread(target=self.send_to_client, args=(socket,)).start()
# 创建线程,负责接收客户端信息并转发给其他客户端
threading.Thread(target=self.recv_from_client, args=(socket,)).start() def send_to_client(self, socket):
"""
获取键盘输入并发送给客户端
:param socket:
:return:
"""
while True:
info = input()
if info == "quit":
socket.close()
for socket in self.socket_mapping.keys():
socket.send(info.encode("utf-8")) def recv_from_client(self, socket):
"""
接收客户端信息并转发给其他客户端
:param socket:
:return:
"""
while True:
recv_info = socket.recv(self.maxSize).decode('utf-8')
print('client{} say: '.format(self.socket_mapping[socket]), recv_info)
for i_socket in self.socket_mapping.keys():
if i_socket != socket:
i_socket.send(recv_info.encode("utf-8")) my_server = MyServer()
my_server.run()

多进程实现socket通信服务器端代码

存在的问题:在与客户端连通后,需要服务器先发送两条消息,之后才能正常通信。

import os
import socket
import sys
from multiprocessing import Process, Manager class MyServer(object):
def __init__(self):
# 初始化socket
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置服务器IP地址
host = '192.168.152.1'
# 设置服务器端口号
port = 4321
# 绑定IP地址和端口
self.server.bind((host, port))
# 设置最大监听数
self.server.listen(5)
# 设置一个字典,用来保存每一个客户端的连接和身份信息
self.socket_mapping = Manager().dict()
# 设置接收的最大字节数
self.maxSize = 1024
# 进程锁
self.share_lock = Manager().Lock() def run(self):
fn = sys.stdin.fileno()
while True:
socket, addr = self.server.accept()
# 发送信息,提示客户端已成功连接
socket.send('success!'.encode('utf-8'))
# 将客户端socket等信息存入字典
self.modify_mapping(self.socket_mapping, addr, socket, self.share_lock)
# 创建进程,负责获取键盘输入并发送给客户端
Process(target=self.send_to_client, args=(addr, fn)).start()
# 创建进程,负责接收客户端信息并转发给其他客户端
Process(target=self.recv_from_client, args=(addr,)).start() def send_to_client(self, addr, fn):
"""
获取键盘输入并发送给客户端
:param addr:
:return:
"""
sys.stdin = os.fdopen(fn)
while True:
info = sys.stdin.readline()
if info == "quit":
self.socket_mapping[addr].close()
for socket in self.socket_mapping.values():
socket.send(info.encode("utf-8")) def recv_from_client(self, addr):
"""
接收客户端信息并转发给其他客户端
:param addr:
:return:
"""
while True:
recv_info = self.socket_mapping.get(addr).recv(self.maxSize).decode('utf-8')
print('client{} say: '.format(addr), recv_info)
for i_addr in self.socket_mapping.keys():
if i_addr != addr:
self.socket_mapping.get(i_addr).send(recv_info.encode("utf-8")) @staticmethod
def modify_mapping(share_var, share_key, share_value, share_lock):
# 获取锁
share_lock.acquire()
# 修改数据
share_var[share_key] = share_value
# 释放锁
share_lock.release() if __name__ == "__main__":
my_server = MyServer()
my_server.run()

异步IO实现socket通信服务器端代码

存在的问题:通信时需要相互发送几次消息后,各自才会收到之前的消息并打印。

import socket
import asyncio
import select class MyServer(object):
def __init__(self):
# 初始化socket
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置服务器IP地址
host = '192.168.152.1'
# 设置服务器端口号
port = 4321
# 绑定IP地址和端口
self.server.bind((host, port))
# 设置最大监听数
self.server.listen(5)
# 设置一个字典,用来保存每一个客户端的连接和身份信息
self.socket_mapping = {self.server: None} # 这里存入self.server是为了充当select.select参数
# 设置接收的最大字节数
self.maxSize = 1024
# 进入事件循环
self.loop = asyncio.get_event_loop() def run(self):
while True:
# select监听请求对象
rret, _, _ = select.select(self.socket_mapping.keys(), [], [])
for r_socket in rret:
if r_socket is self.server:
socket, addr = r_socket.accept()
# 发送信息,提示客户端已成功连接
socket.send('success!'.encode('utf-8'))
# 将客户端socket等信息存入字典
self.socket_mapping[socket] = addr
else:
task = [self.send_to_client(r_socket), self.recv_from_client(r_socket)]
self.loop.run_until_complete(asyncio.gather(*task)) async def send_to_client(self, socket):
"""
获取键盘输入并发送给客户端
:param socket:
:return:
"""
info = input()
if info == "quit":
socket.close()
for socket in self.socket_mapping.keys():
if socket != self.server:
socket.send(info.encode("utf-8")) async def recv_from_client(self, socket):
"""
接收客户端信息并转发给其他客户端
:param socket:
:return:
"""
recv_info = socket.recv(self.maxSize).decode('utf-8')
print('client{} say: '.format(self.socket_mapping[socket]), recv_info)
for i_socket in self.socket_mapping.keys():
if i_socket != socket and i_socket != self.server:
i_socket.send(recv_info.encode("utf-8")) my_server = MyServer()
my_server.run()

客户端代码(使用多线程)

import socket
import threading class MyClient(object):
def __init__(self):
# 初始化socket
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置服务器IP地址
self.host = '192.168.152.1'
# 设置服务器端口号
self.port = 4321
# 设置接收的最大字节数
self.max_size = 1024 def run(self):
# 与服务器建立连接
self.client.connect((self.host, self.port))
# 创建线程,负责获取键盘输入并发送给服务器
threading.Thread(target=self.sned_to_server).start()
# 创建线程,接收服务器信息
threading.Thread(target=self.recv_from_server).start() def sned_to_server(self):
"""
获取键盘输入并发送给服务器
"""
while True:
send_msg = input()
self.client.send(send_msg.encode('utf-8'))
if send_msg == 'quit':
break
self.client.close() def recv_from_server(self):
"""
接收服务器信息
"""
while True:
recv_info = self.client.recv(self.max_size).decode('utf-8')
print('server{} say: '.format((self.host, self.port)), recv_info) my_client = MyClient()
my_client.run()

使用Python实现多线程、多进程、异步IO的socket通信的更多相关文章

  1. Python学习——多线程,异步IO,生成器,协程

    Python的语法是简洁的,也是难理解的. 比如yield关键字: def fun(): for i in range(5): print('test') x = yield i print('goo ...

  2. 多线程/多进程/异步IO

    SOCK_STREAM :TCPSOCK_Dgram :UDP family=AF_INET: 服务器之间的通信AF_INET6: 服务器之间的通信AF_UNIX: Unix不同进程间的通信 永远遵循 ...

  3. Python之路,Day10 - 异步IO\数据库\队列\缓存

    Python之路,Day9 - 异步IO\数据库\队列\缓存   本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitM ...

  4. Day10 - Python协程、异步IO、redis缓存、rabbitMQ队列

    Python之路,Day9 - 异步IO\数据库\队列\缓存   本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitM ...

  5. 从Nginx的Web请求处理机制中剖析多进程、多线程、异步IO

    Nginx服务器web请求处理机制 从设计架构来说,Nginx服务器是与众不同的.不同之处一方面体现在它的模块化设计,另一方面,也是最重要的一方面,体现在它对客户端请求的处理机制上. Web服务器和客 ...

  6. python中同步、多线程、异步IO、多线程对IO密集型的影响

    目录 1.常见并发类型 2.同步版本 3.多线程 4.异步IO 5.多进程 6.总结 1.常见并发类型 I/ O密集型: 蓝色框表示程序执行工作的时间,红色框表示等待I/O操作完成的时间.此图没有按比 ...

  7. Python协程、异步IO

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SS ...

  8. Python高级编程和异步IO并发编程

    第1章 课程简介介绍如何配置系统的开发环境以及如何加入github私人仓库获取最新源码. 1-1 导学 试看 1-2 开发环境配置 1-3 资源获取方式第2章 python中一切皆对象本章节首先对比静 ...

  9. 【Python之路】异步IO

    线程:CPU基本执行单元,可以与同属一个进程的其他线程共享资源,线程是属于进程的. 进程:资源单元,进程一般由程序.数据集.进程控制块三部分组成.一个进程默认有一个主线程, GIL:用于在进程中对所有 ...

  10. python 多协程异步IO爬取网页加速3倍。

    from urllib import request import gevent,time from gevent import monkey#该模块让当前程序所有io操作单独标记,进行异步操作. m ...

随机推荐

  1. Prometheus组件介绍

    Prometheus Server Prometheus Server是Prometheus组件中的核心部分,负责实现对监控数据的获取,存储以及查询. Prometheus Server可以通过静态配 ...

  2. 安全强化Linux 服务器的七个步骤

    这篇入门文章将向你介绍基本的 Linux 服务器安全知识.虽然主要针对 Debian/Ubuntu,但是你可以将此处介绍的所有内容应用于其他 Linux 发行版.我也鼓励你研究这份材料,并在适用的情况 ...

  3. MySQL数据库-数据表(下)

    分析:给 reader 表添加数据. INSERT INTO:插入数据,插入数据的时候会检查主键或者唯一索引,如果出现重复就会报错: 语法:INSERT INTO table_name VALUES ...

  4. 220722 T3 石子染色 (背包)

    序列s中的数就是要选的堆的编号,假设要选的有i个石子,这i个染为红色,剩下j个染为蓝色,i+j=x,i=x-j,那么对答案的贡献是|x-2j|.那么只要我们选的有i个石子,贡献就是这么多,所以我们可以 ...

  5. hive之数据导入导出

    hive数据导入导出 一.导入数据4种方式 建表语句 create table test( name string, friends array, children map<string, in ...

  6. JavaWeb完整案例详细步骤

    JavaWeb完整案例详细步骤 废话少说,展示完整案例 代码的业务逻辑图 主要实现功能 基本的CURD.分页查询.条件查询.批量删除 所使用的技术 前端:Vue+Ajax+Elememt-ui 后端: ...

  7. JVM内存结构模型

  8. HTML基础知识(3)浮动、塌陷问题

    1.浮动 1.1 代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> & ...

  9. C++之值传递&指针传递&引用传递详解

    C++之值传递&指针传递&引用传递详解 目录 C++之值传递&指针传递&引用传递详解 1.函数基础 2.值传递 3.指针传递 4.引用传递 1.函数基础 一个函数由以下 ...

  10. 你所不知道的 vscode,汇集历史版本中你可能不知道的新特性

    壹 ❀ 引 vscode可以毫不夸张的说是大部分前端同学吃饭的工具(webstorm除外),随着时间的推移vscode其实也在不断推出了各种新功能新特性,但vscode并不会默认就实装这些新功能,我相 ...