python tcp通信如何实现多人聊天,Python实现多用户全双工聊天(一对一),python多用户,多用户全双工聊天简陋...

Python实现多用户全双工聊天(一对一),python多用户,多用户全双工聊天简陋

多用户全双工聊天简陋版

简单实现了两个客户端之间的通信,客户端发送消息,先由服务器接收,然后服务器转发到另一客户端。

该版本功能非常简陋,仅仅实现了最简单的聊天,有很多地方需要注意。

工作步骤:服务器端运行一个客户端运行,连接成功后输入用户名,服务器会保存该用户名在一个字典中,字典的对应关系是 username --> socket输入用户名之后,该客户端需要确定一个聊天用户,客户端输入To:user即可;如果客户端发送其他文本的话,会收到来自服务器的提示:“Nobody is chatting with you. Maybe the one talked with you is talking with someone else”当两个客户端成功连接之后就可以互相发送消息

服务器端代码如下:#!/usr/bin/python#coding:utf-8#server.pyfrom socket import *from time import ctimeimport threadingimport reHOST = ‘‘PORT = 9999BUFSIZ = 1024ADDR = (HOST,PORT)tcpSerSock = socket(AF_INET,SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)clients = {} # username -> socketchatwith = {} # user1.socket -> user2.socket# clients字典中记录了连接的客户端的用户名和套接字的对应关系# chatwith字典中记录了通信双方的套接字的对应# messageTransform()处理客户端确定用户名之后发送的文本# 文本只有四种类型:# None# Quit# To:someone# 其他文本def messageTransform(sock,user): while True: data = sock.recv(BUFSIZ) if not data: if chatwith.has_key(sock): chatwith[sock].send(data) del chatwith[chatwith[sock]] del chatwith[sock] del clients[user] sock.close() break if data==‘Quit‘: sock.send(data) if chatwith.has_key(sock): data = ‘%s.‘ % data chatwith[sock].send(data) del chatwith[chatwith[sock]] del chatwith[sock] del clients[user] sock.close() break elif re.match(‘^To:.+‘, data) is not None: data = data[3:] if clients.has_key(data): if data==user: sock.send(‘Please don\‘t try to talk with yourself.‘) else: chatwith[sock] = clients[data] chatwith[clients[data]] = sock else: sock.send(‘the user %s is not exist‘ % data) else: if chatwith.has_key(sock): chatwith[sock].send(‘[%s] %s: (%s)‘ % (ctime(),user,data)) else: sock.send(‘Nobody is chating with you. Maybe the one talked with you is talking with someone else‘) # 每个客户端连接之后,都会启动一个新线程# 连接成功后需要输入用户名# 输入的用户名可能会:# 已存在# (客户端直接输入ctrl+c退出)# 合法用户名def connectThread(sock,test): # client‘s socket user = None while True: # receive the username username = sock.recv(BUFSIZ) if not username: # the client logout without input a name print(‘The client logout without input a name‘) break if clients.has_key(username): # username existed sock.send(‘Reuse‘) else: # correct username sock.send(‘OK‘) clients[username] = sock # username -> socket user = username break if not user: sock.close() return print(‘The username is: %s‘ % user) # get the correct username messageTransform(sock,user) if __name__==‘__main__‘: while True: print(‘...WAITING FOR CONNECTION‘) tcpCliSock, addr = tcpSerSock.accept() print(‘CONNECTED FROM: ‘, addr) chat = threading.Thread(target = connectThread, args = (tcpCliSock,None)) chat.start()

客户端代码如下:#!/usr/bin/python#coding:utf-8#client.pyfrom socket import *from time import ctime# from termios import tcflush,TCIFLUSHimport threadingimport sysHOST = ‘127.0.0.1‘PORT = 9999BUFSIZ = 1024ADDR = (HOST,PORT)tcpCliSock = socket(AF_INET,SOCK_STREAM)tcpCliSock.connect(ADDR)‘‘‘因为每个客户端接收消息和发送消息是相互独立的,所以这里将两者分开,开启两个线程处理‘‘‘def Send(sock,test): while True: try: data = raw_input() sock.send(data) if data==‘Quit‘: break except KeyboardInterrupt: sock.send(‘Quit‘) break def Recv(sock,test): while True: data = sock.recv(BUFSIZ) if data==‘Quit.‘: print(‘He/She logout‘) continue if data==‘Quit‘: break print(‘ %s‘ % data) if __name__==‘__main__‘: print(‘Successful connection‘) while True: username = raw_input(‘Your name(press only Enter to quit): ‘) tcpCliSock.send(username) if not username: break # username is not None response = tcpCliSock.recv(BUFSIZ) if response==‘Reuse‘: print(‘The name is reuse, please set a new one‘) continue else: print(‘Welcome!‘) break if not username: tcpCliSock.close() recvMessage = threading.Thread(target = Recv, args = (tcpCliSock,None)) sendMessage = threading.Thread(target = Send, args = (tcpCliSock,None)) sendMessage.start() recvMessage.start() sendMessage.join() recvMessage.join()

总结:

功能简陋,后续会有所改进。这里还有很多地方需要注意。

比如说两个客户端A成功连接后,和客户端B聊天。A发送消息时直接输入ctrl+c退出程序(sendMessage线程会结束),我将这种情况模拟成A发送Quit登出。服务器接收到A登出信息之后,会回发一个Quit给A,A成功登出(recvMessage线程结束)。此外如果A和B建立了聊天关系,就要接触这个关系,服务器发送Quit.给B,B会继续接收信息,但是服务器端的chatwith字典中已经不存在A.socket --> B.socket关系。

但是还有很多没有解决的问题,比如说客户端A并没有输入信息,直接点击关闭按钮退出,就会发生异常(与之聊天的B客户端会崩溃)。

如果当前存在 A-->B的聊天关系,这时有一个C登录,并且确定了C-->A的聊天关系,那么A会和C聊天,这时客户端B就会被挂起。

主要的问题还是在于客户端非正常登出时的应对,目前解决了一部分问题,但是应该还有不少缺陷。

Python实现多用户全双工聊天(一对一)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab 随机森林算法_随机森林算法

随机森林是一种灵活,易于使用的机器学习算法,即使没有超参数调整,也能在大多数情况下产生出色的结果。它也是最常用的算法之一,因为它简单,并且可以用于分类和回归任务。在这篇文章中,您将学习随机森林算法…

python教程循环语句,Python基础教程之循环语句(for、while和嵌套循环)

循环可以用来重复执行某条语句,直到某个条件得到满足或遍历所有元素。1 for循环是for循环,可以把集合数据类型list、tuple、dict、set的元素遍历出来。(1)对list进行循环city_list [广州,深圳,东莞,佛山]city_list [广州,深圳,东莞,佛山]for city in c…

python课程的中期报告_电子课程设计中期报告

电子线路课程设计中期报告 电信工一班 王绪泉 200900121181 1. 设计题目 设计一个数字显示的电子温度计,要求包含模数转换模块,可数字显示,可测定温 度范围在 0 到 100 摄氏度之间,精度允许误差正负 0.5 摄氏度。 设计思路 本题目…

php-fpm 配置文件位置,php

先清空php-fpm.conf> /usr/local/php/etc/php-fpm.conf输入以下内容:[global]pid /usr/local/php/var/run/php-fpm.piderror_log /usr/local/php/var/log/php-fpm.log[www]listen /tmp/php-fcgi.sockuser php-fpmgroup php-fpmpm dynamicpm.max_children …

opengl 纹理贴到对应的位置_一步步学OpenGL(27) -《公告牌技术与几何着色器》

教程 27公告牌技术与几何着色器原文: http://ogldev.atspace.co.uk/www/tutorial27/tutorial27.htmlCSDN完整版专栏: https://blog.csdn.net/cordova/article/category/9266966背景从最初的一系列教程我们已经应用过了顶点着色器和片段着色器&#xff0c…

thinkphp如何通过php请求接口,thinkphp怎么做json数据接口

function checkUser(){//获取用户名 密码$uname$_GET[uname]; $upass$_GET[upass]; $userM("user");//访问数据库中的t_user表(t_ 以在config.php中设置为表前缀了)$where"uname".$uname." and upass".$upass."";//查询…

python 工资管理软件_基于[Python]的员工管理系统

基于[Python]的员工管理系统 ———————————————————————————————— 简介 使用python语言来完成一个员工管理系统,员工信息包含:员工工号,姓名, 年龄,性别,职位,工…

php执行zip压缩,PHP执行zip与rar解压缩方法实现代码

Zip:PclZip http://www.phpconcept.net/pclzip/index.en.phpRar:PECL rar http://pecl.php.net/package/rar以往过去要在php下执行解压缩程序,无非最常见的方法是写command 然后用exec()等执行函式去跑这在Windows下或许可以,但换…

python 当前目录_virtualenvwrapper打造多版本Python环境

前言面对多个 Python 开发项目时,需要针对不同的项目创建相应的开发环境。通常情况下,使用 virtualenv 创建一个虚拟的独立 Python 环境,但是 virtualenv 创建的环境相对分散不便于管理。这里推荐使用 virtualenvwrapper 来创建集中的便于管理…

oracle装了客户端怎么登陆账号,分享Oracle 11G Client 客户端安装步骤(图文详解)...

Oracle 11G Client 客户端安装步骤,具体如下:下载地址:http://www.gimoo.net/database/167737.html先将下载下来的ZIP文件解压,并运行setup.exe文件。执行到第四步之后,出现错误,直接点全部忽略就可以了。把…

python与excel互通_【python】python vs Excel ( 与mysql数据库之间的交互)

【python】python vs Excel ( 与mysql数据库之间的交互) 通过python与mysql数据库做交互 到目前为止大部分案例的演示数据都是基于文件进行读取的。那么python如何跟数据库之间做交互才是未来我们真正需要关心的。因为我们的数据最终还是要存储到数据库中去的。 python与数据库…

基于matlab的车牌识别系统程序,基于matlab的车牌识别系统的设计(附程序).doc

基于matlab的车牌识别系统的设计(附程序).doc 1车牌识别系统的设计1.摘要:汽车牌照自动识别系统是制约道路交通智能化的重要因素,包括车牌定位、字符分割和字符识别三个主要部分。本文首先确定车辆牌照在原始图像中的水平位置和垂直位置,从而定位车辆牌照…

python删除第一行_Python删除文件第一行

一、代码实例: def del_firstline(): for line in fileinput.input("file.txt", inplace 1): if not fileinput.isfirstline(): print(fileinput.replace("\n", "")) 二、使用的库:fileinput fileinput模块提供处理一个或…

weblogic 11g 配置oracle数据源 数据库驱动选哪个,weblogic11g配置db2数据源驱动有关问题...

weblogic11g配置db2数据源驱动问题今天在weblogic10.33上配置db2 9.7数据源,采用type4方式连接,驱动选择weblogic db2 type4驱动,配置成功后,开启应用测试,发现对元数据的获取存在问题,比如说通过 select *…

python英文词云代码_使用python实现个性化词云的方法

先上图片词云图 需要模板 pip install jieba pip install wordcloud 还需要安装另外两个东西这两个我也不太懂借鉴百度写上去的 pip install scipy pip install matplotlib 因为用ubuntu系统所有没有windows那么麻烦,也没有那么多报错 看到好多人制作自己的词云有没…

php 打开pdf文件附件,pdf里怎么链接到附件

首先试试修改config.inc.php 里的cookie前缀,随便改个试试,例如:$cookiepre FR4_; // cookie 前缀不行的话试试下面的,attachment.php找到function getlocalfile($filename, $readmod 1, $range 0) { if($readmod 1 || $readm…

python numpy库作用_python Numpy库

一.导入库 import numpy as np 二.创建 1.numpy中只有一种数据类型:ndarray,表示n维数组 创建ndarray数组: -由列表或者元组类型创建数组 -有元组类型创建数组 -创建特殊数组 2.采用np.array函数来创建,语法为: np.array(列表或元…

oracle 关闭如何启动,ORACLE启动和关闭实例

实例启动和关闭:一.数据库启动的几种状态(1)SQL>startup 启动的过程:a. 例程启动b. 数据库加载c. 数据库打开(2)SQL>startup nomount例程启动阶段所有做的工作:a. 按以下顺序读取初始化参数文件:首先读取 spfileSID.ora &am…

python文本解析_如何通过python进行文本解析?

我希望使用python解析数据,以便将其导入Excel电子表格中。我需要一些帮助来实现过程的自动化。文件内容包括:ok: [wrt02.test1] > { "msg": "nxos" } TASK [checklist : OUTPUT IOS_XR] ***************************************…

linux监测node进程,通过node_exporter监控linux服务器一

前言:node_exporter用于监控*nux系统,使用go编写的收集器prometheus服务器:192.168.199.222监控服务器 192.168.199.221在192.168.199.221下载node_exporterwget https://github.com/prometheus/node_exporter/releases/download/v*/node_exp…