当前位置: 萬仟网 > IT编程>脚本编程>Python > 用Python制作只属于你和ta的聊天渠道吧

用Python制作只属于你和ta的聊天渠道吧

2019年12月01日 14:58  | 萬仟网IT编程  | 我要评论

前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

作者: python应用宝典

ps:如有需要python学习资料的小伙伴可以加点击下方链接自行获取

原理简介

在我们今天的教程中,将用到即时通讯的概念,即时通讯允许两人或多人同时使用网络传递文字信息、文字、语音等。即时通讯一般都基于socket连接,socket连接可用于发送或接受数据,一般的组合形式是ip+端口号。

也就是说,在我们的例子中,聊天的双方,由一方要承担“服务器 ” 的责任,维持一个socket服务器,等待连接进入;另一方则是“客户端”,在服务器端维持等待状态时即可发送请求,建立连接。

当你和ta想进入“小黑屋 ” 里聊天的时候,只有有一方充当服务器,另一方充当客户端即可,作为“服务器端 ” 的那个人,在微信中将ip和端口号告诉对方,即可构建连接,在小黑屋里聊天,这个小黑屋里的数据不会被任何数据库保留(除非你自己做了一个保存的数据库)。

服务器端

聊天的时候,我们有时候会遇到双方同时发消息的情况。这种聊天方式就叫全双工聊天方式:“服务器”可向“客户端”发送消息,“客户端”也可向“服务端”发送消息,而且允许同时发送消息。

服务器端怎么实现全双工的聊天方式呢?其实很简单,只要用多线程就行了,主线程用于接收客户端的连接,连接成功后新建两个线程:一个用于发送消息,一个用于接收消息:

首先,建立socket服务器:

 1 import socket
 2 import traceback
 3 # 设定ip和端口号
 4 host = ''
 5 port = 51423 
 6 # 建立socket服务器
 7 s = socket.socket(socket.af_inet,socket.sock_stream)
 8 s.bind((host,port))
 9 s.listen() 
10 while true:
11     # 等待连接
12     try:
13         clientsock, clientaddr = s.accept()
14     except keyboardinterrupt:
15         raise
16     except:
17         traceback.print_exc()
18         continue 

 

其中,af_inet指的是用ipv4进行通信,而sock_stream指的是tcp协议。端口号你可以随意设定,服务器端的ip地址默认为空即可。

在while循环中不断等待用户的连接。如果有用户连接成功了,我们将进入下一步,分别建立发送和接受线程:

1 # 建立接收线程
2 t = _thread.start_new_thread(processrecv, (clientsock,))
3  
4 # 建立发送线程
5 r = _thread.start_new_thread(processsend, (clientsock,)) 

 

clientsock就是我们得到的socket连接,processrecv和processsend分别用于处理接受信息和处理发送信息:

 1 import _thread 
 2 def processrecv(clientsock):
 3     """
 4     接受消息
 5         :param clientsock: 客户端的socket连接
 6     """
 7     while true:
 8         data = clientsock.recv(4096)
 9         if not len(data):
10             break
11         print (data.decode('utf-8'))
12     clientsock.close()
13  
14 def processsend(clientsock):
15     """
16     发送消息
17         :param clientsock: 客户端的socket连接
18     """
19     while true:
20         data = input("> ")
21         data = data
22         clientsock.sendall(data.encode('utf-8'))
23     clientsock.close() 

 

有个小细节要注意,socket连接的sendall函数只支持bytes类型的数据,所以我们要encode('utf-8')。

服务端的所有代码就这样,没错,就是这么简单。

客户端

客户端则更简单,主线程本身设定为接受消息,那么我们只需要多一个线程用于发送消息即可。客户端的全部代码如下:

 1 import _thread
 2 import sys
 3 from socket import *
 4  
 5 def send_message(tcpclisock):
 6     """
 7     发送信息
 8         :param tcpclisock: 与服务端的socket连接
 9     """
10     while true:
11         message = input('> ')
12         if not message:
13             break
14         tcpclisock.send(message.encode('utf-8'))
15  
16     tcpclisock.close()
17  
18 if(len(sys.argv) < 3):
19     host = 'localhost'
20     port = 51423
21 else:
22     host = sys.argv[1]
23     port = int(sys.argv[2])
24  
25 bufsiz = 1024
26 addr = (host,port)
27  
28 tcpclisock = socket(af_inet,sock_stream)
29 tcpclisock.connect(addr)
30  
31 # 建立发送消息的线程
32 s = _thread.start_new_thread(send_message, (tcpclisock,))
33  
34 while true:
35     rdata = tcpclisock.recv(bufsiz)
36     if not rdata:
37         break
38     print (rdata.decode('utf-8'))
39     
40 tcpclisock.close() 

 

其中,host部分填写对方的ip,port部分填写端口号。sys.argv用于通过参数输入这两个值,比如我们将客户端文件命名为:client.py, 在cmd中输入:

python client.py 127.0.0.1 51423

能直接传入参数执行脚本,除此之外,其他部分和服务端其实差不多。注意把接受到的数据decode一下(因为我们发的时候encode了)。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

◎已有 0 人评论

Copyright © 2019  萬仟网 保留所有权利. 粤ICP备17035492号-1
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com