网络聊天室python
未经允许,不得转载!
本文提供2种搭建方法,部分来自网络
1-普通
服务端
import socket
import threadingsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.bind(('localhost', 5550))sock.listen(5)
print('Server', socket.gethostbyname('localhost'), 'listening ...')mydict = dict()
mylist = list()#把whatToSay传给除了exceptNum的所有人
def tellOthers(exceptNum, whatToSay):for c in mylist:if c.fileno() != exceptNum :try:c.send(whatToSay.encode())except:passdef subThreadIn(myconnection, connNumber):nickname = myconnection.recv(1024).decode()mydict[myconnection.fileno()] = nicknamemylist.append(myconnection)print('connection', connNumber, ' has nickname :', nickname)tellOthers(connNumber, '【系统提示:'+mydict[connNumber]+' 进入聊天室】')while True:try:recvedMsg = myconnection.recv(1024).decode()if recvedMsg:print(mydict[connNumber], ':', recvedMsg)tellOthers(connNumber, mydict[connNumber]+' :'+recvedMsg)except (OSError, ConnectionResetError):try:mylist.remove(myconnection)except:passprint(mydict[connNumber], 'exit, ', len(mylist), ' person left')tellOthers(connNumber, '【系统提示:'+mydict[connNumber]+' 离开聊天室】')myconnection.close()returnwhile True:connection, addr = sock.accept()print('Accept a new connection', connection.getsockname(), connection.fileno())try:#connection.settimeout(5)buf = connection.recv(1024).decode()if buf == '1':connection.send(b'welcome to server!')#为当前连接开辟一个新的线程mythread = threading.Thread(target=subThreadIn, args=(connection, connection.fileno()))mythread.setDaemon(True)mythread.start()else:connection.send(b'please go out!')connection.close()except : pass
客户端
import socket
import time
import threadingsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect(('localhost', 5550))
sock.send(b'1')
print(sock.recv(1024).decode())
nickName = input('input your nickname: ')
sock.send(nickName.encode())def sendThreadFunc():while True:try:myword = input()sock.send(myword.encode())#print(sock.recv(1024).decode())except ConnectionAbortedError:print('Server closed this connection!')except ConnectionResetError:print('Server is closed!')def recvThreadFunc():while True:try:otherword = sock.recv(1024)if otherword:print(otherword.decode())else:passexcept ConnectionAbortedError:print('Server closed this connection!')except ConnectionResetError:print('Server is closed!')th1 = threading.Thread(target=sendThreadFunc)
th2 = threading.Thread(target=recvThreadFunc)
threads = [th1, th2]for t in threads :t.setDaemon(True)t.start()
t.join()
2-人工智能
服务端
import socket
import time
import tkinter
from tkinter.scrolledtext import ScrolledText
import threading
import requests
import tkinter
from socket import *
from time import ctime
from tkinter import *global Text_Show # 调用人工智能对话的函数,返回人工智能回答def AI_Talk(s):print(s)response = requests.post("http://www.tuling123.com/openapi/api", data={"key": "4105cb6db8c54f5db470b6c0ee42d24b","info": s})response = response.json()answer = response['text']return answer# 线程二函数,用来进行对话def Sever_Thread(sock, caddr):Text_Show.insert('end', "客户端@" + str(caddr[1]) + "已连接!\n")while True:# 接收数据data = str(sock.recv(1024).decode('UTF-8'))if data == "quit":Text_Show.insert('end', "客户端@" + str(caddr[1]) + "终止了对话\n")Text_Show.see(tkinter.END)breakelse:Text_Show.insert('end', "来自客户端@" + str(caddr[1]) + "的消息为:" + data + '\n')Text_Show.see(tkinter.END)# 发送数据time.sleep(0.2)data = AI_Talk(data) ## data = '请输入发送至客户端的数据: 123123' #如果要手动输入的话就要设置好线程sleep时间不然还没有输入,就已经到其他线程了,就会发不出去。sock.sendall(bytes(data, 'UTF-8'))sock.close() # 线程一函数,监听端口,一旦有客户端接入,开启线程二def Sever_Accept(ss):while True:sock, caddr = ss.accept()Thread2 = threading.Thread(target=Sever_Thread, args=(sock, caddr))Thread2.daemon = True # 线程守护Thread2.start()# 服务器初始化
def Sever_Init():HOST = ''PORT = 4700ADDR = (HOST, PORT)ss = socket(AF_INET, SOCK_STREAM, 0)ss.bind(ADDR)ss.listen(20) # 允许最大监听数Thread1 = threading.Thread(target=Sever_Accept, args=(ss,))Thread1.daemon = True # 线程守护Thread1.start()# 主函数if __name__ == "__main__":root = tkinter.Tk()root.title("聊天小程序服务器端 ")frame1 = Frame(root)frame1.pack()IP_Show_Label = Label(frame1, text="默认IP:127.0.0.1\n默认端口为6000\n无法更改!!!")IP_Show_Label.pack(side='left')frame2 = Frame(root)frame2.pack()Text_Show = ScrolledText(frame2, width=100, height=30)Text_Show.bind("<KeyPress>", lambda e: "break")Text_Show.pack(side="bottom", fill='both', expand=True)Sever_Init()root.mainloop()
客户端
import socket
import time
import tkinter
from tkinter.scrolledtext import ScrolledText
import threading
import requests
import tkinter
from socket import *
from time import ctime
from tkinter import *global cs, Text_Show, Send_Show# 发送按键的函数
def Click_Send():sendData = Send_Show.get() # 获取输入内容if sendData == 'quit':Text_Show.insert(tkinter.END, "与服务器连接已断开" + "\n")Text_Show.see(tkinter.END)cs.sendall(bytes(sendData, encoding="utf8"))cs.close()else:Text_Show.insert(tkinter.END, "客户端:" + sendData + "\n")Text_Show.see(tkinter.END)cs.sendall(bytes(sendData, encoding="utf8"))Send_Show.delete(0, END)# 线程函数,循环接受客户端消息
def Receive_Data():while True:accept_data = str(cs.recv(1024), encoding="utf8")Text_Show.insert(tkinter.END, "服务器:" + accept_data + "\n")Text_Show.see(tkinter.END)# 主函数
if __name__ == "__main__":# 初始化GUIroot = tkinter.Tk()root.title("聊天小程序客户端 ")# 顶部显示部分frame1 = Frame(root)frame1.pack()IP_Show_Label = Label(frame1, text="本程序默认IP:127.0.0.1\n默认端口为6000\n无法更改!!!")IP_Show_Label.pack(side='left')# 中部聊天框显示部分frame2 = Frame(root)frame2.pack()Text_Show = ScrolledText(frame2, width=70, height=15)Text_Show.bind("<KeyPress>", lambda e: "break")Text_Show.pack(side="bottom", fill='both', expand=True)# 底部消息发送部分frame3 = Frame(root)frame3.pack()e3 = StringVar()Send_Show = Entry(frame3, textvariable=e3, width=60)buttontext2 = tkinter.StringVar()buttontext2.set('发送')button_Send = tkinter.Button(frame3, width=10, textvariable=buttontext2, command=Click_Send)Send_Show.pack(side="left")button_Send.pack(side="left")frame3.pack()# 初始化TCP协议HOST = '127.0.0.1'PORT = 4700BUFSIZ = 1024ADDR = (HOST, PORT)cs = socket(AF_INET, SOCK_STREAM, 0)cs.connect(ADDR)thread = threading.Thread(target=Receive_Data)thread.start()root.mainloop()
备注
2号有些问题,如又解决,请在聊天室提出,谢谢