1. 程式人生 > >python實現簡單聊天應用(群聊和點對點均實現)

python實現簡單聊天應用(群聊和點對點均實現)

後續程式碼更新和功能新增會提交到個人github主頁,有興趣可以一起來完善!

如果只是拿過去執行看結果,請注意平臺相關性以及python版本號,本示例開發執行平臺為win7x86_64 pycharm community,python版本號為3.5!!!

TALK IS CHEAP, SHOW YOU MY CODE:

客戶端

#coding:utf-8
'''
file:client.py.py
date:2017/9/11 11:01
author:lockey
email:[email protected]
platform:win7.x86_64 pycharm python3
desc:p2p communication clientside
'''
from socket import * import threading,sys,json,re #引入json模組主要是為了資料的封裝傳輸,re的話是做一些合法性的驗證 HOST = '192.168.1.7' PORT=8022 BUFSIZE = 1024 ##緩衝區大小 1K ADDR = (HOST,PORT) myre = r"^[_a-zA-Z]\w{0,}" tcpCliSock = socket(AF_INET,SOCK_STREAM) #建立一個socket連線 userAccount = None #使用者登入標誌,也用來記錄登入的使用者名稱稱 def register
():
#使用者註冊函式 print(""" Glad to have you a member of us! """) accout = input('Please input your account: ') if not re.findall(myre, accout): print('Account illegal!') return None password1 = input('Please input your password: ') password2 = input('Please confirm your password: '
) if not (password1 and password1 == password2): print('Password not illegal!') return None global userAccount userAccount = accout regInfo = [accout,password1,'register'] datastr = json.dumps(regInfo) tcpCliSock.send(datastr.encode('utf-8')) data = tcpCliSock.recv(BUFSIZE) data = data.decode('utf-8') if data == '0': print('Success to register!') return True elif data == '1': print('Failed to register, account existed!') return False else: print('Failed for exceptions!') return False def login(): #使用者登入函式 print(""" Welcome to login in! """) accout = input('Account: ') if not re.findall(myre, accout): print('Account illegal!') return None password = input('Password: ') if not password: print('Password illegal!') return None global userAccount userAccount = accout loginInfo = [accout, password,'login'] datastr = json.dumps(loginInfo) tcpCliSock.send(datastr.encode('utf-8')) data = tcpCliSock.recv(BUFSIZE) if data == '0': print('Success to login!') return True else: print('Failed to login in(user not exist or username not match the password)!') return False def addGroup(): #群組新增 groupname = input('Please input group name: ') if not re.findall(myre, groupname): print('group name illegal!') return None return groupname def chat(target): #進入聊天(群聊和點對點聊天可以選擇) while True: print('{} -> {}: '.format(userAccount,target)) msg = input() if len(msg) > 0 and not msg in 'qQ': if 'group' in target: optype = 'cg' else: optype = 'cp' dataObj = {'type': optype, 'to': target, 'msg': msg, 'froms': userAccount} datastr = json.dumps(dataObj) tcpCliSock.send(datastr.encode('utf-8')) continue elif msg in 'qQ': break else: print('Send data illegal!') class inputdata(threading.Thread): #使用者輸入選擇然後執行不同的功能程式 def run(self): menu = """ (CP): Chat with individual (CG): Chat with group member (AG): Add a group (EG): Enter a group (H): For help menu (Q): Quit the system """ print(menu) while True: operation = input('Please input your operation("h" for help): ') if operation in 'cPCPCpcp': #進入個人聊天 target = input('Who would you like to chat with: ') chat(target) continue if operation in 'cgCGCgcG': #進入群聊 target = input('Which group would you like to chat with: ') chat('group'+target) continue if operation in 'agAGAgaG': #新增群組 groupName = addGroup() if groupName: dataObj = {'type': 'ag', 'groupName': groupName} dataObj = json.dumps(dataObj) tcpCliSock.send(dataObj.encode('utf-8')) continue if operation in 'egEGEgeG': #入群 groupname = input('Please input group name fro entering: ') if not re.findall(myre, groupname): print('group name illegal!') return None dataObj = {'type': 'eg', 'groupName': 'group'+groupname} dataObj = json.dumps(dataObj) tcpCliSock.send(dataObj.encode('utf-8')) continue if operation in 'hH': print(menu) continue if operation in 'qQ': sys.exit(1) else: print('No such operation!') class getdata(threading.Thread): #接收資料執行緒 def run(self): while True: data = tcpCliSock.recv(BUFSIZE).decode('utf-8') if data == '-1': print('can not connect to target!') continue if data == 'ag0': print('Group added!') continue if data == 'eg0': print('Entered group!') continue if data == 'eg1': print('Failed to enter group!') continue dataObj = json.loads(data) if dataObj['type'] == 'cg': #群組訊息的格式定義 print('{}(from {})-> : {}'.format(dataObj['froms'], dataObj['to'], dataObj['msg'])) else: #個人訊息的格式定義 print('{} ->{} : {}'.format(dataObj['froms'], userAccount, dataObj['msg'])) def main(): try: tcpCliSock.connect(ADDR) print('Connected with server') while True: loginorReg = input('(l)ogin or (r)egister a new account: ') if loginorReg in 'lL': log = login() if log: break if loginorReg in 'rR': reg = register() if reg: break myinputd = inputdata() mygetdata = getdata() myinputd.start() mygetdata.start() myinputd.join() mygetdata.join() except Exception: print('error') tcpCliSock.close() sys.exit() if __name__ == '__main__': main()

服務端

#coding:utf-8
'''
file:server.py
date:2017/9/11 14:43
author:lockey
email:[email protected]
platform:win7.x86_64 pycharm python3
desc:p2p communication serverside
'''
import socketserver,json,time
import subprocess

connLst = []
groupLst = []
##  代號 地址和埠 連線物件
#optype = {'ag':'group adding','cp':'chat with individual','cg':'chat with group'}
class Connector(object):   ##連線物件類
    def __init__(self,account,password,addrPort,conObj):
        self.account = account
        self.password = password
        self.addrPort = addrPort
        self.conObj = conObj

class Group(object):#群組類
    def __init__(self,groupname,groupOwner):
        self.groupId = 'group'+str(len(groupLst)+1)
        self.groupName = 'group'+groupname
        self.groupOwner = groupOwner
        self.createTime = time.time()
        self.members=[groupOwner]

class MyServer(socketserver.BaseRequestHandler):

    def handle(self):
        print("got connection from",self.client_address)
        userIn = False
        global connLst
        global groupLst
        while not userIn:
            conn = self.request
            data = conn.recv(1024)
            if not data:
                continue
            dataobj = json.loads(data.decode('utf-8'))
            #如果連線客戶端傳送過來的資訊格式是一個列表且註冊標識為False時進行使用者註冊或者登陸
            ret = '0'
            if type(dataobj) == list and not userIn:
                account = dataobj[0]
                password = dataobj[1]
                optype = dataobj[2]
                existuser = False
                if len(connLst) > 0:
                    for obj in connLst:
                        if obj.account == account:
                            existuser = True
                            if obj.password == password:
                                userIn = True
                                print('{} has logged in system({})'.format(account,self.client_address))
                                break
                if optype == 'login' and (not userIn or not existuser):
                    ret = '1'
                    print('{} failed to logged in system({})'.format(account, self.client_address))
                else:
                    if existuser:
                        ret = '1'
                        print('{} failed to register({}),account existed!'.format(account, self.client_address))
                    else:
                        try:
                            conObj = Connector(account,password,self.client_address,self.request)
                            connLst.append(conObj)
                            print('{} has registered to system({})'.format(account,self.client_address))
                            userIn = True
                        except:
                            print('%s failed to register for exception!'%account)
                            ret = '99'
            conn.sendall(ret.encode('utf-8'))
            if ret == '0':
                break

        while True:
        #除登陸註冊之外的請求的監聽
            conn = self.request
            data = conn.recv(1024)
            if not data:
                continue
            print(data)
            dataobj = data.decode('utf-8')
            dataobj = json.loads(dataobj)
            if dataobj['type'] == 'ag' and userIn:
            #如果判斷使用者操作請求型別為新增群組則進行以下操作
                groupName = dataobj['groupName']
                groupObj = Group(groupName,self.request)
                groupLst.append(groupObj)
                conn.sendall('ag0'.encode('utf-8'))
                print('%s added'%groupName)
                continue

            if dataobj['type'] == 'eg' and userIn:
            #入群操作
                groupName = dataobj['groupName']
                ret = 'eg1'
                for group in groupLst:
                    if groupName == group.groupName:
                        group.members.append(self.request)
                        print('{} added into {}'.format(self.client_address,groupName))
                        ret = 'eg0'
                        break
                conn.sendall(ret.encode('utf-8'))
                continue

            #客戶端將資料發給伺服器端然後由伺服器轉發給目標客戶端
            print('connLst',connLst)
            print('grouplst',groupLst)
            if len(connLst) > 1:
                sendok = False
                if dataobj['type'] == 'cg':
                #群內廣播(除發訊息的人)
                    print('group',data)
                    for obj in groupLst:
                        if obj.groupName == dataobj['to']:
                            for user in obj.members:
                                if user != self.request:
                                    user.sendall(data)
                else:
                #個人資訊傳送
                    for obj in connLst:
                        if dataobj['to'] == obj.account:
                            obj.conObj.sendall(data)
                            sendok = True
                    if sendok == False:
                        print('no target valid!')
            else:
                conn.sendall('-1'.encode('utf-8'))
                continue

if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('192.168.1.7',8022),MyServer)
    print('waiting for connection...')
    server.serve_forever()

執行結果示例

服務端(記錄著各客戶端的操作):
這裡寫圖片描述

客戶端1:
有註冊、建群、群聊、點對點聊天
這裡寫圖片描述

客戶端2:
這裡寫圖片描述

客戶端3:
這裡寫圖片描述

要拷貝程式碼執行的話請注意平臺(win7.x86_64)和python版本號(python3.5)!!!

相關推薦

python實現簡單聊天應用實現

後續程式碼更新和功能新增會提交到個人github主頁,有興趣可以一起來完善! 如果只是拿過去執行看結果,請注意平臺相關性以及python版本號,本示例開發執行平臺為win7x86_64 pycharm community,python版本號為3.5!!! T

python簡單實際應用

初步需求:將一整個資料夾各個子目錄中所有目標檔案的所有對應元素的相同屬性名稱的不同欄位全部取出寫到excel表格以供下一步使用。 整體思路:(1)遞迴出所有目標檔案的地址                  (2)根據地址取出目標檔案的內容                   (3)匹配取出相同屬性的各個欄位 

連結串列 自寫模板一個簡單應用多項式相加相乘

   CreateList(list_own *&L,int n)                         建立連結串列    print(list_own *L)                                             列

C++連線CTP介面實現簡單量化交易行情、交易、k線、策略

對於量化交易來說,量化策略和技術系統缺一不可,為了知其所以然,本文實現了一個C++連線CTP介面進行模擬交易的demo,從接收行情、下訂單、資料處理到新增策略、掛載執行交易等多個環節來看一下量化交易的最簡單流程,管中窺豹,一探究竟。 準備工作 交易所介面 這裡使用上

Netty+Android搭建一個簡易聊天實現

零,前言 JRBM專案中無論是好友私聊,公開聊天室,還是比賽平臺都需要用到長連線,之前沒有接觸過網路通訊等知識,更別說框架了,因此直接上手netty確實有些困難,在前期主要是在b站上看(https://www.bilibili.com/video/av26415011)這個

應用Python實現簡單聊天程式

需求:SCIENCE 和MOOD兩個人軟體專業出身,厭倦了大眾化的聊天軟體,想著自己開發一款簡易的聊天軟體,滿足他們的個性化需求,又不失“專業水準”,Talk is easy, try to code it. 技術:socket,詳細瞭解請參考推酷:pytho

Spring Boot整合websocket實現聊天,圖片傳送,音訊傳送

參考:基於https://blog.csdn.net/qq_38455201/article/details/80374712  基礎上進行新增圖片傳送和音訊傳送功能   單點圖片傳送: 單點音訊傳送: 音訊傳送相關js參考:https://github.

Android端實現多人音視訊聊天應用

本文轉載於資深Android開發者“東風玖哥”的部落格。 本系列文章分享了基於Agora SDK 2.1實現多人視訊通話的實踐經驗。 轉載已經過原作者許可。原文地址 自從2016年,鼓吹“網際網路寒冬”的論調甚囂塵上,2017年亦有愈演愈烈之勢。但連麥直播、線上抓娃

判斷是否在多邊形內的Python實現及小應用射線法

判斷點是否在多邊形內的Python實現及小應用(射線法) 轉 https://www.jianshu.com/p/ba03c600a557 判斷一個點是否在多邊形內是處理空間資料時經常面對的需求,例如GIS中的點選功能、根據多邊形邊界篩選出位於多邊形內的點、求交集、篩選不在多邊形內

基於Socket的Android與PC簡單聊天應用實現

實現Socket聊天其實質就是一個Socket的雙向通訊,分為服務端和客戶端,都是 需要得到一個socket物件,通過socket獲取流得到我們需要的資料。 標準的寫法都是開啟一個while

java WebSocket實現簡單聊天包括群發聊天

今天突然看到了WebSocket然後就網上找了一個例子,然後修改了下,實現了簡單的聊天室,包括群聊和點對點聊天。 使用的程式碼如下 jsp程式碼: <%@ page language="java" import="java.util.*" pageEncoding="

python實現簡單聊天程式

客戶端 #coding:utf-8 import socket, sys host = 'localhost' port = 10001 s = socket.socket(socket.AF_I

Python socket實現簡單聊天

服務端使用了select模組,實現了對多個socket的監控。客戶端由於select在Windows下只能對socket使用,所以使用了多執行緒來實現對客戶端輸入和socket連線的同時監控。注意這裡的

使用Struts2jQuery EasyUI實現簡單CRUD系統——jsp,json,EasyUI的結合

元素 word cli resultset sheet 傳輸 charset {} tco 這部分比較復雜,之前看過自己的同學開發一個選課系統的時候用到了JSON,可是一直不知道有什麽用。寫東西也沒用到。所以沒去學他。然後如今以這樣的懷著好奇心,這是做什麽用的,這是怎麽用

【SSH進階之路】Struts基本原理 + 實現簡單登錄

target doctype 掌握 pack insert enter snippet file manage 上面博文,主要簡單的介紹了一下SSH的基本概念,比較宏觀。作為剛開始學習的人可以有一個總體上的認識,個人覺得對學習有非常好的輔助功能,它不不過

mycat實現簡單的mysql集負載均衡

退出 start ase datanode 文件 1.2 test 開始 select 什麽是mycat呢? 簡單理解為一個MySQL中間件,它支持分流、基於心跳的自動故障切換,支持讀寫分離,支持mysql主從,基於Nio管理線程的高並發… 詳見官網:http://www.

WPF使用socket實現簡單聊天軟件

title poi utf program ces xaml sender ted static 公司網絡限制不能傳文件,先貼部分代碼 項目結構: 1.解決方案 1.1. Client 1.2. Server Client: <Window

websocket實現簡單聊天程序

spa nodejs end 地址 person focus data 實現 完成 程序的流程圖: 主要代碼: 服務端 app.js 先加載所需要的通信模塊: var express = require(‘express‘); var app = express();

使用gluon實現簡單的CNN

bsp evaluate label exce ini rate ati sof name from mxnet import ndarray as nd from mxnet import gluon from mxnet import autograd from mx

實現簡易聊天

ima log body .com 麻煩 導入 定義 右鍵 正常 預備工作: (1)讀取文件的時候可能會遇到多個文件一起傳,可以用線程池。 (2)發送不同類型的請求時,如發送的是聊天信息,發送的是文件,發送的是好友上線請求等,但對於接受者來說都是字節流無法分別,這就需要我們