Python实现网络多人聊天室 - Windows
项目名称:多人聊天室
项目结构:
client.py
server.py
settings.py
项目思路:服务端接收客户端连接,客户端发送信息给服务端,服务端将信息发送给所有客户端。
项目实现:主进程负责接收键盘输入(sys.stdin.readline),使用multiprocessing.Process函数创造一个进程,在这个进程中,使用select监听两个套接字,一个套接字负责服务端与客户端之间的消息接收与发送,另一个负责与主进程保持联系。
# settings.py import os
from socket import *
from random import randint
import shelve HOST = "127.0.0.1" # 服务端和客户端的连接地址
SOCK_PORT = 4444
SOCK_ADDR = HOST, SOCK_PORT # 服务端server.py文件中供pipe_server和pipe_client使用的套接字地址
SER_PIPE_PORT = 4321
SER_PIPE_ADDR = HOST, SER_PIPE_PORT # 客户端client.py文件中供pipe_server和pipe_client使用的套接字地址
# 因为每个客户端都必须有不同的套接字来作起到连接键盘输入和网络套接字之间的管道的作用
# 使用一个文件记录下每一次运行出现的端口号,以保证不重复
if not os.path.exists("ports.dat"):
f = shelve.open("ports")
f["ports"] = []
f = shelve.open("ports")
while True:
n = randint(4500, 10000)
if n not in f["ports"]:
f['ports'].append(n)
break
f.close()
CLI_PIPE_PORT = n CLI_PIPE_ADDR = HOST, CLI_PIPE_PORT # 缓冲区大小
BUFFERSIZE = 1024 # 返回一个TCP服务端套接字
def server(addr):
sock = socket(AF_INET, SOCK_STREAM, 0)
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen(10)
return sock # 返回一个TCP客户端套接字
def client(addr):
sock = socket(AF_INET, SOCK_STREAM, 0)
sock.connect(addr)
return sock
settings.py
# server.py import sys
import shelve
from socket import *
from select import select
from multiprocessing import Process
from settings import * def listen(sock_server, pipe_server):
# IO多路复用:循环监听套接字
rlist = [sock_server, pipe_server]
wlist = []
xlist = [] print("等待连接...")
while True:
rs, ws, xs = select(rlist, wlist, xlist) for r in rs:
if r is sock_server:
# 接受客户端连接
conn, addr = sock_server.accept()
rlist.append(conn)
elif r is pipe_server:
# 接收键盘输入并发送到所有客户端去
conn, addr = pipe_server.accept()
data = conn.recv(BUFFERSIZE)
data = bytes("管理员:", "UTF-8") + data
for c in rlist[2:]:
c.send(data)
conn.close()
else:
# 接收客户端信息
# 将客户端信息发送到所有的客户端中去
try:
data = r.recv(BUFFERSIZE)
except:
r.close()
rlist.remove(r)
else:
print(data.decode(), end="")
for c in rlist[2:]:
c.send(data) def clear_all():
f = shelve.open("ports")
f['ports'].clear()
f.close() if __name__ == '__main__':
# 首先将ports内容都删除
clear_all() # 创建两个套接字
# 套接字sock_server是一个TCP服务端,负责服务端与客户端的交流
# 套接字pipe_server也是一个TCP服务端,不过起到管道的作用,负责接收键盘输入
sock_server = server(SOCK_ADDR)
pipe_server = server(SER_PIPE_ADDR) # 开始一个子进程,执行listen函数
p = Process(target=listen, args=(sock_server, pipe_server))
p.daemon = True
p.start() # 循环接收键盘输入
while True:
try:
# 从标准输入流(键盘)读取一行
data = sys.stdin.readline()
except KeyboardInterrupt:
# 如果遇到退出/中止信号,关闭套接字,结束子进程,退出程序
sock_server.close()
pipe_server.close()
p.terminate()
clear_all()
break if not data:
# 如果从键盘获取数据为空,继续循环
continue
else:
# 获得键盘数据,创建客户端套接字pipe_client,将键盘输入传输给pipe_server
pipe_client = client(SER_PIPE_ADDR)
pipe_client.send(bytes(data, "UTF-8"))
pipe_client.close()
server.py
# client.py import sys
from socket import *
from select import select
from multiprocessing import Process
from settings import * def connect(sock_client, pipe_server, name):
# IO多路复用:循环监听套接字
rlist = [sock_client, pipe_server]
wlist = []
xlist = [] while True:
rs, ws, xs = select(rlist, wlist, xlist) for r in rs:
if r is sock_client:
# 接受服务端的信息
data = sock_client.recv(BUFFERSIZE).decode()
print(data, end="")
elif r is pipe_server:
# 接受键盘输入并发送给服务端
conn, addr = pipe_server.accept()
data = conn.recv(BUFFERSIZE)
data = bytes(name + ":", "UTF-8") + data
sock_client.send(data)
conn.close() def get_name():
return input("User name: ") if __name__ == '__main__':
# 使用get_name函数获得用户名
name = get_name() # 创建两个套接字
# 套接字sock_client是一个TCP客户端,负责服务端与客户端的交流
# 套接字pipe_server也是一个TCP服务端,不过起到管道的作用,负责接收键盘输入
sock_client = client(SOCK_ADDR)
sock_client.send(bytes(name + "加入了聊天室。\n", "UTF-8"))
pipe_server = server(CLI_PIPE_ADDR) # 开始一个子进程,执行connect函数
p = Process(target=connect, args=(sock_client, pipe_server, name))
p.daemon = True
p.start() # 循环接收键盘输入
while True:
try:
# 从标准输入流(键盘)读取一行
data = sys.stdin.readline()
except KeyboardInterrupt:
# 如果遇到退出/中止信号,发送退出信息,关闭套接字,结束子进程,退出程序
sock_client.send(bytes(name + "退出了聊天室。\n", "UTF-8"))
sock_client.close()
pipe_server.close()
p.terminate()
break if not data:
# 如果从键盘获取数据为空,继续循环
continue
else:
# 获得键盘数据,创建客户端套接字pipe_client,将键盘输入传输给pipe_server
pipe_client = client(CLI_PIPE_ADDR)
pipe_client.send(bytes(data, "UTF-8"))
pipe_client.close()
client.py

Python实现网络多人聊天室 - Windows的更多相关文章
- Python实现网络多人聊天室
网络多人聊天室 文件结构: chatroom ├── client.py # 客户端代码 ├── language.py # 语言文件 ├── server.py # 服务端代码 └── set ...
- Python实现网络图形化界面多人聊天室 - Windows
Python实现网络图形化界面多人聊天室 - Windows 项目名称:网络多人聊天室图形界面版本 项目思路: server.py 服务端文件,主进程中,创建图形化界面,询问地址(主机名,端口),点击 ...
- Python实现网络图形化界面多人聊天室 - Linux
网络图形化界面多人聊天室 - Linux Windows版本:https://www.cnblogs.com/noonjuan/p/12078524.html 在Python实现网络多人聊天室基础上, ...
- 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室
原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室
原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 66 网络编程(五)——TCP多线程实现多人聊天室
思路 客户端读写各一个类,可以使内部类,实现Runnable.读写类都与服务器端建立连接,一个收,一个发. 客户端实现接收和转发.多线程实现每个客户端的连接(使与各客户端的连接独立). 服务器端中创建 ...
- Apache MiNa 实现多人聊天室
Apache MiNa 实现多人聊天室 开发环境: System:Windows JavaSDK:1.6 IDE:eclipse.MyEclipse 6.6 开发依赖库: Jdk1.4+.mina-c ...
- 多人聊天室(Java)
第1部分 TCP和UDP TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全:常用于一般不要求速度和需要准确发送消息的场 ...
- 使用Go语言+Protobuf协议完成一个多人聊天室
软件环境:Goland Github地址 一.目的 之前用纯逻辑垒完了一个可登入登出的在线多人聊天室(代码仓库地址),这次学习了Protobuf协议,于是想试着更新下聊天室的版本. 主要目的是为了掌握 ...
随机推荐
- Django3.0 前瞻 支持异步通信
最近两年,Django的版本号提升得特别快,2.0还没有多久,很快就要到3.0了. 让我们先看看官方的路线图和时间表: 版本号 发布日期 停止更新日期 停止维护日期 3.0 2019-12 2020- ...
- JUnit & JMockit单元测试
JUnit&JMockit单元测试总结 1.JUnit简介 Java单元测试框架业内应用较多的是JUnit,它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的 ...
- onload()方法只能在body标签中调用吗?怎么调用多个多个方法?
第一个问题: onload()方法并非只能在body标签中调用的,还可以在js中用window.onload = function() {函数名};来调用:另外img等标签也支持onload方法. 支 ...
- [ Python入门教程 ] Python生成随机数模块(random)使用方法
1.使用randint(a,b)生成指定范围内的随机整数.randint(a,b)表示从序列range([a,b])中获取一个随机数,包括b. >>> random.randint( ...
- [题解向] CF#Global Round 1の题解(A $\to$ G)
这里是总链接\(Link\). \(A\) 题意:求\(\sum_{i=1}^{k} a_i\times b^{k-i}\)的奇偶性, \(k = \Theta(n \log n)\) --其实很容易 ...
- angularjs中ng-class常用写法,三元表达式、评估表达式与对象写法
壹 ❀ 引 ng-class可以说在angularjs样式开发中使用频率特别高了,这不我想利用ng-class的三元运算符的写法来定义一个样式,结果怎么都想不起来正确写法,恼羞成怒还是整理一遍吧,那 ...
- 《细说PHP》第四版 样章 第二章 PHP的应用与发展 1
<细说PHP>第四版 样章 第二章 PHP的应用与发展 1 学习任何编程语言之前,先了解一下它的应用与发展是很有必要的.从Web开发的历史看来,PHP.Python和Ruby几乎是同时出现 ...
- appium应用切换以及toast弹出框处理
一.应用切换 应用切换的方法很简单,直接调用driver.start_activity()方法,传入app_package和app_activity参数,示例代码如下: from appium imp ...
- 转载:点云上实时三维目标检测的欧拉区域方案 ----Complex-YOLO
感觉是机器翻译,好多地方不通顺,凑合看看 原文名称:Complex-YOLO: An Euler-Region-Proposal for Real-time 3D Object Detection ...
- java核心技术第六篇之断言、日志、包装类型和工具类
JDK1.5新特性: 1.自动拆装箱. 2.泛型 3.可变参数 4.静态导入 5.增强for循环 6.互斥锁 7.枚举 8.注解 JDK1.6新特性: 1.Desktop类和SystemTray类 2 ...