python 点对点聊天_python实现简单聊天应用 python群聊和点对点均实现

本文介绍了一个使用Python编写的点对点聊天和群聊应用程序。通过socket库实现客户端和服务器端的通信,包括用户注册、登录、群组添加、入群以及聊天功能。代码适用于win7x86_64平台,Python版本为3.5。用户输入选择功能,如个人聊天、群聊、添加群组等,并通过JSON进行数据传输。
摘要由CSDN通过智能技术生成

后续代码更新和功能添加会提交到个人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:lockey@123.com

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:lockey@123.com

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)!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值