Python网络编程(子进程的创建与处理、简单群聊工具)
Unix/Linux操作系统提供了一个
fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是
fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。子进程永远返回
0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用
getppid()就可以拿到父进程的ID。Python的
os模块封装了常见的系统调用,其中就包括fork,可以在Python程序中轻松创建子进程
- 父进程创建子进程等待进程退出
- 子进程创建下一个进程,然后立即退出
- 二级子进程成为孤儿进程 处理具体工作
1.需要将要做的事情封装为函数2.使用multiprocessing提供的process 创建进程对象3.通过进程对象和process初始化进程进行进程的设置,绑定函数4.启动进程,会自动执行绑定的函数5.完成进程的回收
- 使用multiprocessing创建进程子进程同样复制父进程的全部内存空间
- 之后有自己的独立空间 执行上互不干扰 子进程也有自己的PID特有资源等
- 使用multiprocessing创建子进程,一般父进程功能就是创建子进程
- 回收子进程,返回事件交给子进程完成
from socket import *
import os, sys # 发送管理员消息
def do_child(s, addr):
while True:
msg = input("管理员消息:")
msg = "C 管理员 " + msg
s.sendto(msg.encode(), addr) # 用户登录
def do_login(s, user, name, addr):
if (name in user) or name == "管理员":
s.sendto("该用户已存在".encode(), addr)
return
s.sendto(b'OK', addr)
# 通知所有人
msg = "\n欢迎 %s 进入聊天室" % name
for i in user:
s.sendto(msg.encode(), user[i])
# 插入user
user[name] = addr def do_chat(s, user, name, data):
msg = "\n{} 说: {}".format(name, data)
for i in user:
if i != name:
s.sendto(msg.encode(), user[i]) def do_quit(s, user, name):
msg = "\n%s 离开了聊天室" % name
for i in user:
if i == name:
s.sendto(b'EXIT', user[i])
else:
s.sendto(msg.encode(), user[i])
del user[name] # 删除离开的用户 # 接收客户端请求并处理
def do_parent(s):
# 用于存储用户 {'Alex':('127.0.0.1',8888)}
user = {}
while True:
msg, addr = s.recvfrom(1024)
msgList = msg.decode().split(' ')
if msgList[0] == 'L':
do_login(s, user, msgList[1], addr)
elif msgList[0] == 'C':
# "C Levi [I miss you]"
data = ' '.join(msgList[2:])
do_chat(s, user, msgList[1], data)
elif msgList[0] == 'Q':
do_quit(s, user, msgList[1]) # 创建套接字,网络连接,创建父子进程
def main():
# server address
ADDR = ('0.0.0.0', 8888)
# 创建套接字
s = socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
s.bind(ADDR) # 创建父子进程
pid = os.fork()
if pid < 0:
sys.exit("创建进程失败")
elif pid == 0:
do_child(s, ADDR)
else:
do_parent(s) if __name__ == "__main__":
main()
from socket import *
import sys, os def login(s, ADDR):
while True:
name = input("请输入用户名:")
msg = "L " + name
s.sendto(msg.encode(), ADDR)
# 接收登录结果
data, addr = s.recvfrom(1024)
if data.decode() == 'OK':
print("@进入聊天室@")
return name
else:
print(data.decode()) # 发送消息
def do_child(s, name, addr):
while True:
text = input("发言(quit退出):")
# 退出
if text.strip() == "quit":
msg = "Q " + name
s.sendto(msg.encode(), addr)
sys.exit("退出聊天室") msg = "C %s %s" % (name, text)
s.sendto(msg.encode(), addr) # 接收消息
def do_parent(s):
while True:
msg, addr = s.recvfrom(1024)
if msg.decode() == 'EXIT':
sys.exit(0)
print(msg.decode() + "\n发言(quit退出):",end="") # main控制套接字的创建
def main():
if len(sys.argv) < 3:
print("argv is error")
return
HOST = sys.argv[1]
PORT = int(sys.argv[2])
ADDR = (HOST, PORT) s = socket(AF_INET, SOCK_DGRAM) name = login(s, ADDR)
if name:
pid = os.fork()
if pid < 0:
sys.exit("创建子进程失败")
elif pid == 0:
do_child(s, name, ADDR)
else:
do_parent(s)
else:
return if __name__ == "__main__":
main()
Python网络编程(子进程的创建与处理、简单群聊工具)的更多相关文章
- Java网络编程Demo,使用TCP 实现简单群聊功能Groupchat,创建一个服务端,使多个客户端都能收到消息
效果图: 开启服务端 客户端一 客户端二 客户端三 实现代码: 客户端类 import java.io.IOException; import java.net.ServerSocket; impor ...
- Java网络编程Demo,使用TCP 实现简单群聊功能GroupchatSimple,多个客户端输入消息,显示在服务端的控制台
效果: 服务端 客户端 实现代码: 服务端 import java.io.IOException; import java.net.ServerSocket; import java.net.Sock ...
- python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)
python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...
- 图解Python网络编程
返回目录 本篇索引 (1)基本原理 (2)socket模块 (3)select模块 (4)asyncore模块 (5)asynchat模块 (6)socketserver模块 (1)基本原理 本篇指的 ...
- Python 网络编程(二)
Python 网络编程 上一篇博客介绍了socket的基本概念以及实现了简单的TCP和UDP的客户端.服务器程序,本篇博客主要对socket编程进行更深入的讲解 一.简化版ssh实现 这是一个极其简单 ...
- Python 网络编程(一)
Python 网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...
- Python学习(22)python网络编程
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
- Day07 - Python 网络编程 Socket
1. Python 网络编程 Python 提供了两个级别访问网络服务: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口 ...
- python网络编程-01
python网络编程 1.socket模块介绍 ①在网络编程中的一个基本组件就是套接字(socket),socket是两个程序之间的“信息通道”. ②套接字包括两个部分:服务器套接字.客户机套接字 ③ ...
随机推荐
- 2017.10.13 Java中引用类型变量的创建及使用&循环高级写法
今日内容介绍 1.引用类型变量的创建及使用 2.流程控制语句之选择语句 3.流程控制语句之循环语句 4.循环高级 ###01创建引用类型变量公式 * A: 创建引用类型变量公式 ...
- aop 和castle 的一些 学习文章
https://www.cnblogs.com/zhaogaojian/p/8360363.html
- Java 类加载体系之 ClassLoader 双亲委托机制
Java 类加载体系之 ClassLoader 双亲委托机制 java 是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件 ...
- 第4章 初识STM32—零死角玩转STM32-F429系列
第4章 初识STM32 集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资 ...
- redis事务中的WATCH命令和基于CAS的乐观锁
转自:http://blog.sina.com.cn/s/blog_ae8441630101cgy3.html 在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能. ...
- React后台管理系统-品类选择器二级联动组件
1.页面大致是这个样子 2.页面结构 <div className="col-md-10"> <select name="&quo ...
- 如何使用MongoDB+Springboot实现分布式ID?
转载请标明出处: http://blog.csdn.net/forezp/article/details/69056017 本文出自方志朋的博客 一.背景 如何实现分布式id,搜索相关的资料,一般会给 ...
- Lucene检索提高性能的几个方式
1.采用最新版本的Lucene 2.索引文件存储采用本地文件系统,如果需要挂载远程系统,请采用 readonly方式. 3.当然采用更好的硬件,更高I/O的磁盘 4.提高OS 缓存,调整参数 5.提高 ...
- 【模板时间】◆模板·II◆ 树链剖分
[模板·II]树链剖分 学长给我讲树链剖分,然而我并没有听懂,还是自学有用……另外感谢一篇Blog +by 自为风月马前卒+ 一.算法简述 树链剖分可以将一棵普通的多叉树转为线段树计算,不但可以实现对 ...
- ORM初级实战简单的数据库交互
setting.py中: """ Django settings for untitled3 project. Generated by 'django-admin st ...