程序实现:
1、单或多客户端使用 telnet 登陆服务端 ( 可远程 ) 进行会话
2、服务端实现登陆、注册、退出功能
3、客户端发送的消息会被广播到已经登陆的其他用户界面
4、连接到服务端后,可以执行相应的程序指令 程序代码:https://coding.net/u/wangxiaoqiangs/p/pycode/git/tree/master/socket/GServer GServer.py #!/usr/bin/env python
# coding: utf-8
# author: Xiao Guaishou import socket
from db import DB
from threading import currentThread, Thread class HandlerThread(object):
queue = [] # sockect 队列
db = DB() def __init__(self, sock):
self.sock = sock def recv(self):
data = self.sock.recv(1024).strip() # 如果使用 while 接收数据时,会导致用户必须多敲一次回车键
return data def send(self, data):
self.sock.sendall('\n[System]: %s\n' % data) # 向队列中广播消息
def broadcast(self, user, data):
for sock in self.queue:
sock.sendall('\n[%s]: %s\n' % (user, data)) # 关闭客户端连接
def stop(self):
self.send('ByeBye!')
self.sock.close()
self.queue.remove(self.sock) # 关闭连接后,记得从队列中删除 # 程序入口
def handler(self):
funcdict = {
'login': self.login,
'register': self.register
} try:
thname = currentThread().getName()
print('[%s] Got connection from %s' % (thname, self.sock.getpeername())) # 该程序中所有 print 的数据,将全部使用 loging 模块代替 self.send('请选择功能:login/register/exit') data = self.recv()
if data == 'exit':
self.stop() # 其实这里应该单独使用 self.sock.close() 来关闭连接,因为这时队列中并没有该连接,不过有了下面的捕获就没有问题了 ^_^
elif data in funcdict:
return funcdict.get(data)()
else:
self.handler()
except: # 如果这里不捕获一下,就无法正常断开客户端连接
pass # 处理用户登陆
def login(self):
self.send('Login... 请输入用户名密码,格式:User Password,输入 Server: 执行程序指令!')
user_data = self.recv() # 程序内部指令
if user_data == 'Server:':
self.send('\n\tServer:use reged\t切换到注册页\n\tServer:exit\t\t退出系统')
user_data = self.recv()
if user_data == 'Server:use reged':
self.register()
elif user_data == 'Server:exit':
self.stop()
else:
self.send('输入错误...') datalist = user_data.split() # 判断用户输入,格式是否正确
if len(datalist) == 2:
user = datalist[0]
password = datalist[1] db_data = self.db.get_data() or {} if user in db_data and password == db_data.get(user):
self.queue.append(self.sock) # 有权限登陆系统者,连接被加入到队列中
self.send('欢迎加入聊天室,输入 Server: 获取功能方法!')
self.broadcast('System', '[%s] 加入聊天室!' % user)
self.chat_room(user)
else:
self.send('用户名、密码错误!')
self.login()
self.login() def register(self):
self.send('Register... 请输入用户名密码,格式:User Password,输入 Server: 执行程序指令!')
user_data = self.recv() if user_data == 'Server:':
self.send('\n\tServer:use login\t切换到注册页\n\tServer:exit\t\t退出系统')
user_data = self.recv()
if user_data == 'Server:login':
self.login()
elif user_data == 'Server:exit':
self.stop()
else:
self.send('输入错误...') datalist = user_data.split() if len(datalist) == 2:
user = datalist[0]
password = datalist[1] db_data = self.db.get_data() or {} if user in db_data:
self.send('该用户名已被注册!')
self.register()
else:
db_data[user] = password
self.db.put_data(db_data)
self.queue.append(self.sock)
self.broadcast('System', '新用户 [%s] 加入聊天室!' % user)
self.chat_room(user)
self.register() def chat_room(self, user):
user_data = self.recv()
if user_data == 'Server:':
self.send('\n\tServer:logout\t退出聊天室')
user_data = self.recv()
if user_data == 'Server:logout':
self.stop()
return # 这里如果不加 return ,会将客户端执行的 Server: 指令也广播出去
else:
self.send('输入错误...')
self.chat_room(user)
else:
self.broadcast(user, user_data)
self.chat_room(user) # 为每连接创建线程
def Startthread(sock, addr):
print('Received new client connection. %s:%s' % (addr[0], addr[1])) th = HandlerThread(sock)
t = Thread(target=th.handler)
t.setDaemon(True)
t.start() # 启动服务
def Server():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 17170))
s.listen(1) while True:
try:
sock, addr = s.accept()
except KeyboardInterrupt:
exit('\nByeBye!') Startthread(sock, addr) s.close() if __name__ == '__main__':
Server() db.py # coding: utf-8 import json # 创建一个类,代替数据库
class DB(object):
def __init__(self, path='Storage.db'):
self.path = path def get_data(self, data=None):
try:
with open(self.path) as f:
data = json.load(f)
except IOError as e:
return data # 首次取数据时,由于文件不存在或没数据,将返回默认值 None
finally:
return data def put_data(self, data):
with open(self.path, 'w') as f:
json.dump(data, f)

Python 多人聊天工具 ( 多线程 )的更多相关文章

  1. Python多人聊天室

    一.目的 以实现小项目的方式,来巩固之前学过的Python基本语法以及相关的知识. 二.相关技术: 1.wxpython GUI编程 2.网络编程 3.多线程编程 4.数据库编程 5.简单的将数据导出 ...

  2. python 开发简单的聊天工具

    python 太强大了,以至于它什么都可以做,哈哈,开个玩笑.但是今天要讲的真的是一个非常神奇的应用. 使用python写一个聊天工具 其实大家平时用的QQ类似的聊天工具,也是使用socket进行聊天 ...

  3. python 开发简单的聊天工具-乾颐堂

    python 太强大了,以至于它什么都可以做,哈哈,开个玩笑.但是今天要讲的真的是一个非常神奇的应用. 使用python写一个聊天工具 其实大家平时用的QQ类似的聊天工具,也是使用socket进行聊天 ...

  4. [更新Github地址]python学习,自己写了个简单聊天工具mychat

    最近在学习python,自己写了个最最简单的聊天工具mychatv0.1. 第一版,完成基本的聊天功能. GUI用的是自带的TKinter,用到的模块主要就是socket(网络编程), thread( ...

  5. python网络聊天器多线程版

    在之前的一篇文章(python网络编程-udp)中实现了一个简单的udp聊天器,只能在单线程下进行收发数据,在学习完多线程之后,实现一个能同时收发数据的udp聊天器. 说明: 编写一个有2个线程的程序 ...

  6. 基于tcp和多线程的多人聊天室-C语言

    之前在学习关于网络tcp和多线程的编程,学了知识以后不用一下总绝对心虚,于是就编写了一个基于tcp和多线程的多人聊天室. 具体的实现过程: 服务器端:绑定socket对象->设置监听数-> ...

  7. python模拟QQ聊天室(tcp加多线程)

    python模拟QQ聊天室(tcp加多线程) 服务器代码: from socket import * from threading import * s = socket(AF_INET,SOCK_S ...

  8. 一个Java编写的小玩意儿---多人在线聊天工具

    这个在线聊天工具小项目使用JAVA编写,用JAVA来做图形界面本来就是出了名的低效和丑陋.不过这不是重点.写这个小项目的目的在于串一串J2SE的知识,把当时写这个项目的时候的思路梳理一下.时间有点久了 ...

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

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

随机推荐

  1. 每天一个linux命令(文件操作):【转载】find命令之xargs

    在使用 find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行.但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出 ...

  2. BZOJ2330 SCOI2011 糖果 【差分约束】

    BZOJ2330 SCOI2011 糖果 Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一 ...

  3. UWP 流畅设计中的光照效果(容易的 RevealBorderBrush 和不那么容易的 RevealBackgroundBrush)

    在 Windows 10.0.16299 中,RevealBrush 被引入,可以实现炫酷的鼠标滑过高亮效果和点击光照.本文将告诉大家如何完整地实现这样的效果. Reveal 的效果(自带) 在微软官 ...

  4. 《DSP using MATLAB》示例 Example 6.11

    上代码: % x = -7:7 y = OnesComplement(x, 4) 函数OnesComplement代码: function [y] = OnesComplement(x, B); % ...

  5. UVA11806 Cheerleaders

    题意 PDF 分析 如果要求是某行某列没有石子很好算,就一个组合数. 然后要求某行某列有,就用容斥原理就行了. 时间复杂度\(O(k^2 + 16T)\) 代码 #include<iostrea ...

  6. drone 学习五 集成gitlab 配置以及简单测试

    备注: 使用docker-compose  进行安装 同时集成gitlab,预备环境 docker  docker-compose  gitlab 1. docker-compose version: ...

  7. Shell脚本一键安装LNMP环境

    https://sourceforge.net/projects/opensourcefile/files/ Nginx是一款高性能的HTTP和反向代理服务器.Nginx在反向代理,Rewrite规则 ...

  8. vue的动画组件(transition)

    当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理: 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名. v-enter: 定 ...

  9. RK3288 手动设置电池电量

    参考:[RK3288][Android6.0] 调试笔记 --- 电池电量一直显示100% 系统版本:RK3288 android 5.1 (与参考的变量和宏有点区别) 设备没有电池,在进行Fota升 ...

  10. js事件篇

    javascript和html之间的交互式通过事件来实现的,事件就是文档或浏览器窗口中发生的一些特定的交互. 事件流:描述的是从页面中接收事件的顺序. 不同的是,IE和Netscape开发团队竟然提出 ...