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协议,于是想试着更新下聊天室的版本. 主要目的是为了掌握 ...
随机推荐
- echarts常用说明
import { Injectable } from '@angular/core'; //模板option通用 let fff7 = '#fff'; //字体统一颜色rgba(255,255,255 ...
- 解决Fiddler在win7系统下的安全证书问题
如果电脑win7系统,一直解决不了Fiddler的证书安装问题,可以试试下面的办法. 在安装证书的时候一直遇到这个问题. 这是因为win7系统的在.net Framework4.0上面的bug引起的. ...
- LVS负载均衡实现双向热备
一.LVS1服务器配置 安装ipvsadm,keepalived [root@localhost ~]# yum -y install ipvsadm keepalived 配置keepalivedd ...
- php处理curl的返回结果
最简单的方式: json_decode($res,true): 结果都是:
- python做中学(六)os.getcwd() 的用法
概述 os.getcwd() 方法用于返回当前工作目录. 语法 getcwd()方法语法格式如下: os.getcwd() 参数 无 返回值 返回当前进程的工作目录. 实例 以下实例演示了 getcw ...
- css兄弟选择器,+ ~选择器的区别
壹 ❀ 引 实习生在写搜索框下拉提示时,遇到了不知道怎么解决的问题,所以来问我.效果不难,鼠标选中输入框(focus)时,展示搜索关键字相关提示,看了眼dom结构是这样的: 在她的理解里面,选中父元 ...
- HTTP常见的几种认证机制
几种常用的认证机制 ===================转自https://www.cnblogs.com/xiekeli/红心李的文章====================== 我是一个测试人员 ...
- LinqMethod 实现 LeftJoin
LinqMethod 实现 LeftJoin Intro 有时候我们想实现 leftJoin 但是 Linq 提供的 Join 相当于是 INNER JOIN,于是就打算实现一个 LeftJoin 的 ...
- hash算法原理及应用漫谈【加图版】
原文:https://blog.csdn.net/Tencent_TEG/article/details/103021226 提到hash,相信大多数同学都不会陌生,之前很火现在也依旧很火的技术区块链 ...
- Java内功心法,Set集合的详解
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...