项目名称:多人聊天室
项目结构:
  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的更多相关文章

  1. Python实现网络多人聊天室

    网络多人聊天室 文件结构: chatroom ├── client.py  # 客户端代码 ├── language.py  # 语言文件 ├── server.py  # 服务端代码 └── set ...

  2. Python实现网络图形化界面多人聊天室 - Windows

    Python实现网络图形化界面多人聊天室 - Windows 项目名称:网络多人聊天室图形界面版本 项目思路: server.py 服务端文件,主进程中,创建图形化界面,询问地址(主机名,端口),点击 ...

  3. Python实现网络图形化界面多人聊天室 - Linux

    网络图形化界面多人聊天室 - Linux Windows版本:https://www.cnblogs.com/noonjuan/p/12078524.html 在Python实现网络多人聊天室基础上, ...

  4. 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

    原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  5. 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室

    原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  6. 66 网络编程(五)——TCP多线程实现多人聊天室

    思路 客户端读写各一个类,可以使内部类,实现Runnable.读写类都与服务器端建立连接,一个收,一个发. 客户端实现接收和转发.多线程实现每个客户端的连接(使与各客户端的连接独立). 服务器端中创建 ...

  7. Apache MiNa 实现多人聊天室

    Apache MiNa 实现多人聊天室 开发环境: System:Windows JavaSDK:1.6 IDE:eclipse.MyEclipse 6.6 开发依赖库: Jdk1.4+.mina-c ...

  8. 多人聊天室(Java)

    第1部分 TCP和UDP TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全:常用于一般不要求速度和需要准确发送消息的场 ...

  9. 使用Go语言+Protobuf协议完成一个多人聊天室

    软件环境:Goland Github地址 一.目的 之前用纯逻辑垒完了一个可登入登出的在线多人聊天室(代码仓库地址),这次学习了Protobuf协议,于是想试着更新下聊天室的版本. 主要目的是为了掌握 ...

随机推荐

  1. 手动更新了packages.config Nuget配置文件,自动引用dll

    通过Google查询到:http://stackoverflow.com/questions/6876732/how-do-i-get-nuget-to-install-update-all-the- ...

  2. wepy安装后提示Cannot read property 'addDeps'

    最近准备做一个微信小程序,以前一直用的小程序原始api做,但是这次准备用一个框架来做练习,当然在做之前需要比较一下现在小程序框架的优缺点. 经过认真挑选,选定wepy,Taro,uni-app,mpv ...

  3. Codeforces Round #603 (Div. 2) E. Editor 线段树

    E. Editor The development of a text editor is a hard problem. You need to implement an extra module ...

  4. 说说 Vue.js 中的 v-cloak 指令

    可以使用 v-cloak 指令设置样式,这些样式会在 Vue 实例编译结束时,从绑定的 HTML 元素上被移除. 当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示 ...

  5. error while loading shared libraries

    https://stackoverflow.com/questions/480764/linux-error-while-loading-shared-libraries-cannot-open-sh ...

  6. Python 学习 第16篇:数据类型(字典和Json)

    字典是键/值对构成的集合,字典通过大括号来创建,字典的键是字符串,而值可以是任何数据对象. 字典有两个重要的特征: 字典是无序的,字典项没有特定的顺序,只能通过键来获取值: 字典是可变的,支持原处修改 ...

  7. mysql Hash索引和BTree索引区别

    Hash仅支持=.>.>=.<.<=.between.BTree可以支持like模糊查询 索引是帮助mysql获取数据的数据结构.最常见的索引是Btree索引和Hash索引. ...

  8. nodejs通过钉钉群机器人推送消息

    nodejs 通过钉钉群机器人推送消息 Intro 最近在用 nodejs 写爬虫,之前的 nodejs 爬虫代码用 js 写的,感觉可维护性太差,也没有智能提示,于是把js改用ts(typescri ...

  9. 关于excel中的vlookup就是查找当前列对应的下一列的值的使用

    关于excel中的vlookup就是查找当前列对应的下一列的值的使用 vlookup的使用一些说明 vlookup函数一个4个参数解释下 vlookup(查找的值,表格范围,表格范围中第几列的值,0是 ...

  10. 第2个word发布的博客

      //接收的为空时,则表示客户端下线,跳出循环 if (r == 0) { break; }; string str = Encoding.UTF8.GetString(buffer, 0, r); ...