python网络编程案例--基于TCP在线聊天程序-爱代码爱编程
本程序主要通过在服务器端设计一个ServerUI类,封装接收消息的方法receiveMessage(self),发送消息sendMessage(self),并在构造函数中完成Tkinter界面布局。
在服务器端建立Socket并绑定5505后循环接收客户端的连接请求,当服务器与客户建立连接后,如果客户端发送字符Y,服务器端收到后会返回字符Y信息,表明连接建立,连接后双方便可以不断接收客户端发来的消息了。
1.服务端程序
import sys
import tkinter
import tkinter.font as tkFont
import socket
import threading
import time
# noinspection PyAttributeOutsideInit,PySimplifyBooleanCheck
class ServerUI():
local = '127.0.0.1'
port = 5505
global serverSock;
flag = False
# 初始化类的相关属性的构造函数
def __init__(self):
self.root = tkinter.Tk()
self.root.title('python在线聊天-服务器端v1.0')
# 窗口面板,用四个frame面板布局
self.frame = [tkinter.Frame(),tkinter.Frame(),tkinter.Frame(),tkinter.Frame()]
# 显示消息Text右边的滚条
self.chatTextScrollBar = tkinter.Scrollbar(self.frame[0])
self.chatTextScrollBar.pack(side=tkinter.RIGHT,fill=tkinter.Y)
# 显示消息Text,并绑定上面的滚动条
ft = tkFont.Font(family='Fixdsys',size=11)
self.chatText = tkinter.Listbox(self.frame[0],width=70,height=18,font=ft)
self.chatText['yscrollcommand'] = self.chatTextScrollBar.set
self.chatText.pack(expand=1,fill=tkinter.BOTH)
self.chatTextScrollBar['command'] = self.chatText.yview()
self.frame[0].pack(expand = 1,fill=tkinter.BOTH)
# 标签,分开消息显示Text和消息输入Text
label = tkinter.Label(self.frame[1],height = 2)
label.pack(fill = tkinter.BOTH)
self.frame[1].pack(expand = 1,fill = tkinter.BOTH)
# 输入消息Text的滚动条
self.inputTextScrollBar = tkinter.Scrollbar(self.frame[2])
self.inputTextScrollBar.pack(side = tkinter.RIGHT,fill = tkinter.Y)
# 输入消息Text,并与滚动条绑定
ft = tkFont.Font(family='Fixdsys',size=11)
self.inputText = tkinter.Text(self.frame[2],width = 70,height = 8,font = ft)
self.inputText['yscrollcommand'] = self.inputTextScrollBar.set
self.inputText.pack(expand = 1,fill = tkinter.BOTH)
self.inputTextScrollBar['command'] = self.chatText.yview()
self.frame[2].pack(expand=1,fill = tkinter.BOTH)
# 发送按钮
self.sendButton = tkinter.Button(self.frame[3],text = '发送',width = 10,command=self.sendMessage)
self.sendButton.pack(expand = 1,side = tkinter.BOTTOM and tkinter.RIGHT,padx = 25,pady=5)
# 关闭按钮
self.closeButton = tkinter.Button(self.frame[3],text = '关闭',width = 10,command = self.close)
self.closeButton.pack(expand = 1,side = tkinter.RIGHT,padx =25,pady =5)
self.frame[3].pack(expand = 1,fill = tkinter.BOTH)
# 接收消息
def receiveMessage(self):
# 建立socket连接
self.serverSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.serverSock.bind((self.local,self.port))
self.serverSock.listen(15)
self.buffer = 1024
self.chatText.insert(tkinter.END,'服务器已经就绪........')
# 循环接收客户端的连接请求
while True:
self.connection,self.address = self.serverSock.accept()
self.flag = True
while True:
self.clientMsg = self.connection.recv(self.buffer).decode('utf-8')
if not self.clientMsg:
continue
elif self.clientMsg == 'Y':
self.chatText.insert(tkinter.END,'服务器已经与客户端建立连接.......')
self.connection.send(b'Y')
elif self.clientMsg =='N':
self.chatText.insert(tkinter.END,'服务器和客户端建立连接失败........')
self.connection.send(b'N')
else:
theTime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
self.chatText.insert(tkinter.END,'客户端'+theTime+'说: \n')
self.chatText.insert(tkinter.END,' '+self.clientMsg)
# 发送消息
def sendMessage(self):
# 得到用户在Text中输入的消息
message = self.inputText.get('1.0',tkinter.END)
# 格式化当前时间
theTime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
self.chatText.insert(tkinter.END,'服务器'+theTime+'说:\n')
self.chatText.insert(tkinter.END,' '+message +'\n')
if self.flag == True :
# 将消息发送到客户端
self.connection.send(message.encode())
else:
# Socket 连接没有建立用户,提示用户
self.chatText.insert(tkinter.END,'你还未与客户端建立连接,客户端无法收到你的消息\n')
# 清空用户在Text中输入的消息
self.inputText.delete(0.0,message.__len__()-1.0)
# 关闭消息窗口并退出
def close(self):
sys.exit()
# 启动线程接收客户消息
def startNewThread(self):
thread = threading.Thread(target=self.receiveMessage,args=())
thread.setDaemon(True);
thread.start();
def main():
server = ServerUI()
server.startNewThread()
server.root.mainloop()
if __name__ =='__main__':
main()
二,python在线聊天程序客户端
在客户端设计ClientUI类,封装接收信息函数方法receiveMessage(self),发送消息sendMessage(self),并构造函数中完成TKinter界面布局。
客户端建立Socket后,向服务器发送字符Y,表示客户端要连接服务器,服务器收到后返回字符Y信息,表示连接成功,在建立连接成功后即可不断接收服务器发来的聊天信息。
客户端程序
import threading
import tkinter
import tkinter.font as tkFont
import socket
import sys
import time
class ClientUI():
local = '127.0.0.1'
port = 5505
global clientSock;
flag = False
def __init__(self):
self.root = tkinter.Tk()
self.root.title('python在线聊天-客户端v1.0')
# 窗口面板,用四个frame面板布局
self.frame = [tkinter.Frame(), tkinter.Frame(), tkinter.Frame(), tkinter.Frame()]
# 显示消息Text右边的滚条
self.chatTextScrollBar = tkinter.Scrollbar(self.frame[0])
self.chatTextScrollBar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
# 显示消息Text,并绑定上面的滚动条
ft = tkFont.Font(family='Fixdsys', size=11)
self.chatText = tkinter.Listbox(self.frame[0], width=70, height=18, font=ft)
self.chatText['yscrollcommand'] = self.chatTextScrollBar.set
self.chatText.pack(expand=1, fill=tkinter.BOTH)
self.chatTextScrollBar['command'] = self.chatText.yview()
self.frame[0].pack(expand=1, fill=tkinter.BOTH)
# 标签,分开消息显示Text和消息输入Text
label = tkinter.Label(self.frame[1], height=2)
label.pack(fill=tkinter.BOTH)
self.frame[1].pack(expand=1, fill=tkinter.BOTH)
# 输入消息Text的滚动条
self.inputTextScrollBar = tkinter.Scrollbar(self.frame[2])
self.inputTextScrollBar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
# 输入消息Text,并与滚动条绑定
ft = tkFont.Font(family='Fixdsys', size=11)
self.inputText = tkinter.Text(self.frame[2], width=70, height=8, font=ft)
self.inputText['yscrollcommand'] = self.inputTextScrollBar.set
self.inputText.pack(expand=1, fill=tkinter.BOTH)
self.inputTextScrollBar['command'] = self.chatText.yview()
self.frame[2].pack(expand=1, fill=tkinter.BOTH)
# 发送按钮
self.sendButton = tkinter.Button(self.frame[3], text='发送', width=10, command=self.sendMessage)
self.sendButton.pack(expand=1, side=tkinter.BOTTOM and tkinter.RIGHT, padx=25, pady=5)
# 关闭按钮
self.closeButton = tkinter.Button(self.frame[3], text='关闭', width=10, command=self.close)
self.closeButton.pack(expand=1, side=tkinter.RIGHT, padx=25, pady=5)
self.frame[3].pack(expand=1, fill=tkinter.BOTH)
# 接收信息
def receiveMessage(self):
try:
# 建立Socket连接
self.clientSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.clientSock.connect((self.local,self.port))
self.flag = True
except:
self.flag = False
self.chatText.insert(tkinter.END,'你还未与服务器建立连接,请检查服务器是否启动')
return
self.buffer = 1024
self.clientSock.send('Y'.encode()) # 向服务器端发送字符Y,表示客户端要连接服务器
while True:
try:
if self.flag == True:
self.serverMsg = self.clientSock.recv(self.buffer).decode('utf-8')
if self.serverMsg =='Y':
self.chatText.insert(tkinter.END,'客户端已经与服务器端建立连接.....')
elif self.serverMsg == 'N':
self.chatText.insert(tkinter.END,'客户端与服务器端建立连接失败....')
elif not self.serverMsg:
continue
else:
thetime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
self.chatText.insert(tkinter.END,'服务器端'+thetime+'说:\n')
self.chatText.insert(tkinter.END,' '+self.serverMsg)
else:
break
except EOFError as msg:
raise msg
self.clientSock.close()
break
#发送消息
def sendMessage(self):
message = self.inputText.get('1.0',tkinter.END)
#格式化当前时间
thetime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
self.chatText.insert(tkinter.END, '客户端' + thetime + '说:\n')
self.chatText.insert(tkinter.END, ' ' + message +'\n')
if self.flag == True:
self.clientSock.send(message.encode());
else:
self.chatText.insert(tkinter.END,'你还未与服务器端建立连接,服务器端无法收到你的消息\n')
self.inputText.delete(0.0,message.__len__()-1.0)
# 关闭消息窗口并退出
def close(self):
sys.exit()
# 启动线程接收服务器端消息
def startNewThread(self):
thread =threading.Thread(target = self.receiveMessage,args = ())
thread.setDaemon(True);
thread.start();
def main():
client = ClientUI()
client.startNewThread()
client.root.mainloop()
if __name__ == '__main__':
main()
运行结果:
1.先运行服务器端:截图如下:
2.客户端运行结果:
3.连接成功,开始聊天;
欢迎各路大佬,互相讨论学习!
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/qq_44176343/article/details/108365338