1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > python聊天室详细教程_python简单实现聊天室功能(代码教程)

python聊天室详细教程_python简单实现聊天室功能(代码教程)

时间:2024-02-24 10:11:07

相关推荐

python聊天室详细教程_python简单实现聊天室功能(代码教程)

聊天室程序需求:

我们要实现的是简单的聊天室的例子,就是允许多个人同时一起聊天,每个人发送的消息所有人都能接收到,类似于 QQ 群的功能,而不是点对点的 QQ 好友之间的聊天。如下图:

这里我们首先要知道《python网络编程》知识,其中要明白什么是Socket以及如何使用Socket 实现不同主机间的通信。

OK,我这里直接上TCP版本的server.py和client.py文件

运行时分别运行server.py和client.py文件即可,或者在编译器上直接运行,效果图在文章末尾。

server.py

# -*- encoding:utf-8 -*-

# socket.getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0)

# 根据给定的参数host/port,相应的转换成一个包含用于创建socket对象的五元组,

# 参数host为域名,以字符串形式给出代表一个IPV4/IPV6地址或者None.

# 参数port如果字符串形式就代表一个服务名,比如“http”"ftp""email"等,或者为数字,或者为None

# 参数family为地主族,可以为AF_INET ,AF_INET6 ,AF_UNIX.

# 参数socktype可以为SOCK_STREAM(TCP)或者SOCK_DGRAM(UDP)

# 参数proto通常为0可以直接忽略

# 参数flags为AI_*的组合,比如AI_NUMERICHOST,它会影响函数的返回值

# 附注:给参数host,port传递None时建立在C基础,通过传递NULL。

# 该函数返回一个五元组(family, socktype, proto, canonname, sockaddr),同时第五个参数sockaddr也是一个二元组(address, port)

# 更多的方法及链接请访问

# Echo server program

#socket - tcp - server.py(服务端):

from socket import *

import sys

import threading

from time import ctime

from time import localtime

import traceback

import time

import subprocess

reload(sys)

sys.setdefaultencoding("utf8")

HOST = '127.0.0.1'

PORT = 8555 # 设置侦听端口

BUFSIZ = 1024

class TcpServer():

def __init__(self):

self.ADDR = (HOST, PORT)

try:

self.sock = socket(AF_INET, SOCK_STREAM)

print '%d is open' % PORT

self.sock.bind(self.ADDR)

self.sock.listen(5)

# 设置退出条件

self.STOP_CHAT = False

# 所有监听的客户端

self.clients = {}

self.thrs = {}

self.stops = []

except Exception, e:

print "%d is down" % PORT

return False

def IsOpen(ip, port):

s = socket(AF_INET, SOCK_STREAM)

try:

s.connect((ip, int(port)))

# s.shutdown(2)

# 利用shutdown()函数使socket双向数据传输变为单向数据传输。shutdown()需要一个单独的参数,

# 该参数表示s了如何关闭socket。具体为:0表示禁止将来读;1表示禁止将来写;2表示禁止将来读和写。

print '%d is open' % port

return True

except:

print '%d is down' % port

return False

def listen_client(self):

while not self.STOP_CHAT:

print(u'等待接入,侦听端口:%d' % (PORT))

self.tcpClientSock, self.addr = self.sock.accept()

print(u'接受连接,客户端地址:', self.addr)

address = self.addr

# 将建立的client socket链接放到列表self.clients中

self.clients[address] = self.tcpClientSock

# 分别将每个建立的链接放入进程中,接收且分发消息

self.thrs[address] = threading.Thread(target=self.readmsg, args=[address])

self.thrs[address].start()

time.sleep(0.5)

def readmsg(self, address):

# 如果地址不存在,则返回False

if address not in self.clients:

return False

# 得到发送消息的client socket

client = self.clients[address]

while True:

try:

# 获取到消息内容data

data = client.recv(BUFSIZ)

except:

print error

self.close_client(address)

break

if not data:

break

# python3使用bytes,所以要进行编码

# s='%s发送给我的信息是:[%s] %s' %(addr[0],ctime(), data.decode('utf8'))

# 对日期进行一下格式化

ISOTIMEFORMAT = '%Y-%m-%d %X'

stime = time.strftime(ISOTIMEFORMAT, localtime())

s = u'%s发送给我的信息是:%s' % (str(address), data.decode('utf8'))

# 将获得的消息分发给链接中的client socket

for k in self.clients:

self.clients[k].send(s.encode('utf8'))

self.clients[k].sendall('sendall:' + s.encode('utf8'))

print str(k)

print [stime], ':', data.decode('utf8')

# 如果输入quit(忽略大小写),则程序退出

STOP_CHAT = (data.decode('utf8').upper() == "QUIT")

if STOP_CHAT:

print "quit"

self.close_client(address)

print "already quit"

break

def close_client(self, address):

try:

client = self.clients.pop(address)

self.stops.append(address)

client.close()

for k in self.clients:

self.clients[k].send(str(address) + u"已经离开了")

except:

pass

print str(address) + u'已经退出'

if __name__ == '__main__':

tserver = TcpServer()

tserver.listen_client()

client.py

# -*- encoding:utf-8 -*-

from socket import *

import sys

import threading

import time

#socket - tcp - client.py (客户端):

reload(sys)

sys.setdefaultencoding("utf8")

# 测试,连接本机

HOST = '127.0.0.1'

# 设置侦听端口

PORT = 8555

BUFSIZ = 1024

class TcpClient:

ADDR = (HOST, PORT)

def __init__(self):

self.HOST = HOST

self.PORT = PORT

self.BUFSIZ = BUFSIZ

# 创建socket连接

self.client = socket(AF_INET, SOCK_STREAM)

self.client.connect(self.ADDR)

# 起一个线程,监听接收的信息

self.trecv = threading.Thread(target=self.recvmsg)

self.trecv.start()

def sendmsg(self):

# 循环发送聊天消息,如果socket连接存在则一直循环,发送quit时关闭链接

while self.client.connect_ex(self.ADDR):

data = raw_input('>:')

if not data:

break

self.client.send(data.encode('utf8'))

print(u'发送信息到%s:%s' % (self.HOST, data))

if data.upper() == "QUIT":

self.client.close()

print u"已关闭"

break

def recvmsg(self):

# 接收消息,如果链接一直存在,则持续监听接收消息

try:

while self.client.connect_ex(self.ADDR):

data = self.client.recv(self.BUFSIZ)

print(u'从%s收到信息:%s' % (self.HOST, data.decode('utf8')))

except Exception, e:

print str(e)

if __name__ == '__main__':

client = TcpClient()

client.sendmsg()

结果展示:

我运行了两次client.py文件,表示我有两个用户进行通信,服务器会接收到两个用户发送的消息。

server.py

client.py

第一个用户首先与服务器连接

第二个用户也进来了,现在两个用户之间可以相互发送消息了

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。