zoukankan      html  css  js  c++  java
  • 用Python制作只属于你和ta的聊天渠道吧

    前言

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

    作者: Python应用宝典

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

    http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef

    原理简介

    在我们今天的教程中,将用到即时通讯的概念,即时通讯允许两人或多人同时使用网络传递文字信息、文字、语音等。即时通讯一般都基于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了)。

  • 相关阅读:
    python isinstance函数 判断元素是否是字符串、int型、float型
    Day04 list(列表)
    Day 05 Dict字典
    Python的简介
    DAY7 字符编码和文件操作
    DAY6 元组、字典与集合
    DAY5 基本数据类型及内置方法
    DAY4 if、while和for
    DAY3 数据类型与运算符
    DAY2 初识python
  • 原文地址:https://www.cnblogs.com/Qqun821460695/p/11962530.html
Copyright © 2011-2022 走看看