首先,我们需要知道实现怎么样的聊天:

1、不是单工或者半双工

2、我可以发消息,也可以不发消息,并且不影响我收消息

3、我的消息不会发给自己,我的消息可以发给其他所有人

4、暂时没有GUI,只要会做了,弄一个GUI界面是很简单的,我过两天有时间再弄一个

知道这几点要求后,还需要知道实现的方法:

1、基本的socket知识(客户端是用单纯的socket做的)

2、基本的socketserver知识(服务器是用socketserver做的,也可以使用socket+select做),socketserver里面的TCPServer,ThreadingMaxIn两个模块

3、使用简单的线程知识(threaing),这个在客户端获取输入时要求不能阻塞了程序而使用。

这里面几个模块要想全部理解有点难,但仅仅是用一下,还是很简单的,(比如:笔者也有大量不会的地方,很多地方只是会用,特别是threading模块)

下面,分步来完成这个软件:

第一步:服务端,可以接受到来自客户端发送的消息

from socketserver import TCPServer,ThreadingMixIn,StreamRequestHandler

class Server(ThreadingMixIn,TCPServer):

pass

class Handler(StreamRequestHandler):

def handle(self):

self.request.setblocking(0)        #设置为非阻塞模式

addr = self.request.getpeername()#获取客户端的地址(host,port)

print("连接的客户端地址:%s"%(addr,))

while 1:            #这一块是用来接收消息的

try:

data = self.request.recv(1024)

print(data.decode())

except BlockingIOError:

pass

server = Server(('127.0.0.1',13333),Handler)#启动服务器

server.serve_forever()#将服务器挂起,检查是否有事件发生(客户端请求连接)

在简书里面空格打得不是很方便,所以缩进有问题,但是最好不要直接复制粘贴,最好自己手打一遍。

在这段代码中,Server继承了ThreadingMixIn和TCPServer两个类,继承TCPServer是因为我们用的是tcp连接,当有客户端连接,就会触发Handler(),继承ThreadingMixIn是为了能够连接多个客户端,如果不继承这个的话,就只能连接一个客户端(底层的原理我也不是很清楚)。

self.request这个可以类比为s = socket.socket(),我觉得可能socket和socketserver两个都是继承来自一个更底层的套接字模块(我不确定),所以他们的方法也几乎相同,self.request.recv()等同于s.recv()。

self.request.setblocking(0)        #设置为非阻塞模式,看网上很多都没讲清楚怎么用这个,我也是前几天看着一个很好的博客才懂了这个,这个参数为0设置为非阻塞模式之后,收发消息会变成非阻塞模式的,并且会报BlockingIOError的错,所以需要异常处理。参数如果为正数好像是设置阻塞时间(没有验证过)。

第二步:差不多了,开始写客户端的代码

import socket,threading

s = socket.socket()

host = socket.gethostbyname("127.0.0.1")#我不是很请楚这个函数的作用,它的返回值还是"127.0.0.1",没变化,也可以不要这个方法,直接写地址就行

port =13333

s.connect((host,port))#连接服务器

id =1#这是本来准备用来给一个编号的,不过后来想想还是让服务器给编号比较好

def get_input():#获得输入,这是一个子线程

while 1:

data =input("》》")

s.send(data.encode())

while 1:

threading_input = threading.Thread(target=get_input)

threading_input.start()#开始子线程

print(s.recv(1024).decode(encoding="utf-8",errors='ignore'))

这里需要说一下的就是threading_input = threading.Thread(target=get_input),target的参数是你需要执行的子线程的函数名。

另外需要注意的就是编码问题最好设置为强制编码,不报错。

待会你可以创建两个客户端连接服务器,然后他们就可以相互通信,不过现在显然是不可以的,服务器并没有想着要发送信息,那么就先来。

第三步:让服务器开始发信息

其实知道了前面的知识,后面的你自己尝试就可以完成,我直接把最终的代码贴出来,并讲述其中需要注意的地方

from socketserverimport TCPServer,ThreadingMixIn,StreamRequestHandler

data_list = []#这里是要点1

class Server(ThreadingMixIn,TCPServer):

pass

class Handler(StreamRequestHandler):

def handle(self):

#设置为非阻塞模式

self.request.setblocking(0)

addr =self.request.getpeername()

select.append(addr)

print("连接的客户端地址:%s"%(addr,))

while 1:

#这一块是用来接收消息的

try:

data =self.request.recv(1024)

data = (data,addr)

data_list.append(data)

except:

pass

#下面一块都是用来发消息的

for iin data_list:

if addr == i[1]:

continue

try:

self.request.sendall(i[0])

data_list.remove(i)#这一句话涉及了共有变量的修改,会报错

except BlockingIOError:

continue

except ValueError:#这里是要点2

continue

server = Server(('127.0.0.1',13333),Handler)

server.serve_forever()

要点一:线程中只有全局变量是共享的,而且可以相互通信,那么我就利用全局变量来实现将消息发给所有的客户端(除了自己,一个简单的条件判断而已)

要点二:这个也是有变量共享引起的,讲到这个,我就必须讲一下线程,线程和进程的关系大家应该都知道,不知道可以百度,相对应进程,线程最大的优点就是可以相互通信,但是一个缺点是,在Python中,(下面我谈一下我的理解,虽然看了很多资料,但是我还是不怎么确定),线程在Python中也不是完全同步进行的,是通过时间轮询执行的(个人看法,网上很多大神讲过这个,我说的好像有点问题,不过这只是现在的理解),在极短的时间内,进行着切换,那么现在有一个问题了,一个共享变量很有可能我取到了,但是当我执行下一句代码的时候,这个被另一个线程处理掉了。(这就是我所与到的问题,也有可能是线程通过多核同步进行也会遇到这样的问题,所以我说我不确定。标准的方法是设定锁,不过锁的话有点麻烦,我直接用异常处理来解决了)

说完了,第四步就是设置一个GUI界面,并且再完善一下就可以用来多人聊天啦~@^@~

python制作聊天软件_一步一步教你做聊天软件(Python实现+非阻塞)相关推荐

  1. python制作表白神器_程序员的七夕用30行代码让Python化身表白神器

    转眼又到了咱们中国传统的情人节七夕了,今天笔者就带大家来领略一下用Python表白的方式.让程序员的恋人们感受一下IT人的浪漫. 一.词云制作 首先咱们可以用之前介绍过的wordcould包制作词云. ...

  2. python制作ppt动画_天呐,还能这么玩!用 Python 生成动态 PPT

    在工作的过程中,我们会发现那些能够把知识.成果讲透的人很多都会做动态图表. 这篇文章就介绍了 Python 中一种简单的动态图表制作方法,这样生成的动图就可以丰富我们的PPT啦~ 数据暴增的年代,数据 ...

  3. 如何用python制作三维动画_用Python制作3D动画

    很多小伙伴可能不知道,在3D动画甚至电影制作的过程中,Python也在其中扮演了很重要的角色呢! 比如皮克斯的动画片一般使用Maya软件制作,并且流程中使用到了大量的Maya Python插件. 另外 ...

  4. python制作pdf教程_学以致用:Python爬取廖大Python教程制作pdf!

    学以致用:Python爬取廖大Python教程制作pdf! python-tutorial-pdf 当我学了廖大的Python教程后,感觉总得做点什么,正好自己想随时查阅,于是就开始有了制作PDF这个 ...

  5. python制作应用程序_如何将python应用制作成容器镜像?

    能不能一次部署,处处运行?其实这个问题已经有点过时了,别问,问就是 docker,如果你了解过 docker,你就知道,以容器的形式来发布你的应用程序,已经变得非常流行. 本文教你如何将一个 Pyth ...

  6. python制作音乐模块_用Python打造一个只属于你的专属音乐播放器,享受动手的快乐!...

    平常我们总是用爬虫爬取网页上的音乐,今天我们换个玩法,用Python制作一个独一无二只属于你的音乐播放器,小伙伴们觉得如何?如果觉得提议还不错,那就立即动手吧! 一.需要的库 pygame tkint ...

  7. python制作文字识别_用Python轻松进行图像文本识别

    用Python轻松进行图像文本识别 作者:梅朵 微信公众号:实用办公编程技能 微信号:Excel-Python 最近,办公室的同事小李在整理一份报告,很多材料的电子版找不到了,都是纸质版的,纸质版上的 ...

  8. python制作圣诞贺卡_简单好看的圣诞贺卡手工制作方法 圣诞节卡片怎么做

    圣诞贺卡的手工制作教程有很多有比较简单的圣诞贺卡制作图解教程,也有比较复杂的手工制作圣诞贺卡的制作方法,不同的圣诞贺卡制作方法不同,制作出来的效果也是完全不同的,这对于喜欢手工圣诞贺卡制作的同学而言, ...

  9. python做出来的小程序、可以在win10上面运行_超详细,手把手教你用20行Python代码制作飞花令小程序!...

    原标题:超详细,手把手教你用20行Python代码制作飞花令小程序! 来源:早起Python 作者:陈熹 飞花令是古时候人们经常玩一种"行酒令"的游戏,是中国古代酒令之一,属雅令. ...

最新文章

  1. UVa563 - Crimewave
  2. 代码这样写更优雅(Python版)
  3. java选中一格_java-选中排序(新手)
  4. 最近遇到的jsfl开发问题总结
  5. java url json字符串_JAVA中带有JSON字符串的HTTP POST请求
  6. 爬虫python下载电影_python爬虫:抓取下载电影文件,合并ts文件为完整视频
  7. u深度重装系统详细教程_u深度u盘装系统教程 u深度u盘装系统步骤
  8. matlab 元素 最大值和最小值,[转载]matlab中的最大值和最小值
  9. 西门子802d数控立式加工中心智能调节参数
  10. LAMP平台部署及应用_wuli大世界_新浪博客
  11. python爬取豆瓣图书前250
  12. 从源码分析Redis分布式锁的原子性保证
  13. 如何做一个根据自己的需求做一个完美的商品详情页?
  14. linux 下的进程创建线程,Linux线程 之 线程 线程组 进程 轻量级进程(LWP)
  15. 城市夜景照明对于安科瑞智能照明系统的运用
  16. oracle如何设置连接数,关于Oracle连接数设置
  17. 使用 arxiv-sanity 实时跟进自己研究领域的Paper
  18. 回文数(Java解法)
  19. 实习生风采 · 贰 | 张倬胜同学:攻关「孟子」轻量化预训练模型
  20. RADIUS 服务器之 hostapd 配置说明

热门文章

  1. 必读的AI和深度学习博客
  2. 产品嘚吧嘚系列:大学城020产品模式研讨
  3. fish or cut bait 当机立断
  4. 网络爬虫---用urllib模块爬取京东笔记本电脑的数据、并对其做一个可视化
  5. 正版求生之路联机服务器已满,求生之路2正版怎么联机 正版的联机方法
  6. HBuilder X下载安装,运行微信小程序教程(官网)
  7. 计算机中如何美化表格,手把手教你如何一秒美化Excel表格
  8. 解决T100设计器无法更新基础数据的幺蛾子
  9. python安装第三方包_python 怎么安装第三方包
  10. OTA自动化测试解决方案