代码编织梦想

本程序主要通过在服务器端设计一个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

P站-画师通图片如何保存为原图-爱代码爱编程

进入P站-画师通 P站-画师通 打开F12,选中一个图片找到html 找到href https://www.huashi6.com/ + href就是下一级页面 进入子页面,打开F12,选中图片 其中data-original连接是图片地址 https://img2.huashi6.com/images/resource/2018

python提取字符串中的中文、数字、字母-爱代码爱编程

转载自:https://blog.csdn.net/luoganttcc/article/details/80946194 #\d 匹配一个数字字符。等价于 [0-9] #\D 匹配一个非数字字符。等价于 [^0-9] #过滤字符串中的英文与符号,保留汉字 import re st = "hello,world!!%[545]你好234世界。。。" s

python--数据结构--部分背包-爱代码爱编程

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 。 贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。也就是说,不从整体最优上加以考虑,做出的只是在某种意义上的局部最优解 。 算法思路 贪心算法一般按如下步骤进行 ①建立数学模型来描述问题

python中获取字典中的key,value值的方法-爱代码爱编程

获取一个字典中的key,value值有多种方法,现总结一下,直接上代码: dictss={'username': 'zhouchuanlun', 'code': '66666'} # #获取key值,value值 for k,v in dictss.items(): print(k,v) # #方法1:获取key值 for name in di

商业数据分析【四】商务智能—Python应用Ⅰ-爱代码爱编程

商务智能   BI(Business Intelligence)即商务智能,它是一套完整的解决方案,用来将企业中现有的数据进行有效的整合,快速准确的提供报表并提出决策依据,帮助企业做出明智的业务经营决策。   常见BI:Oracle,SAP,Microsoft; Python   Python排名   开发工具Pycharm =  不

css快速入门_CSS视口单位:快速入门-爱代码爱编程

css快速入门 It’s been a few years since viewport units were first introduced in CSS. They’re truly “responsive length units” in the sense that their value changes every time the brow

Tkinter实现登录成功后进入主界面-爱代码爱编程

今天我们来用tkinter实现一下登录,然后进入软件界面的操作,核心就是用到一个方法wait_window(window=None) 话不多说直接撸代码。 '''先写个登录框框吧,直接上函数吧,类真的累''' def login(master): login_frame = tk.Frame(master) login_frame.g

Python—使用tkinter制作一个小时钟-爱代码爱编程

网上搬运的,自己又调试了一下,分享一下 # coding:utf-8 from tkinter import * import math,time def points(): for i in range(1,13): x = 200 + 130*math.sin(2*math.pi*i/12) y = 200 - 130*math.

数独游戏怎么解?python算法告诉你!!!上篇-爱代码爱编程

数独游戏怎么解? 这是我写的一款数独游戏软件,下面就一步一步看下怎么架构出来的吧 首先是UI 是一个九宫格里套一个九宫格,再套一个九宫格的button if __name__ == "__main__": window = tkinter.Tk() window_x = 1050 window_y = 900 scree

python tkinter 图片插入问题-爱代码爱编程

通过tkinter.PhotoImage插入GIF, PGM/PPM格式的图片。 import tkinter class Gui: def __init__(self): self.gui=tkinter.Tk() # cre

一个完整简单而又强力的计算器程序--用python实现(Python3.7)-爱代码爱编程

注释都在文中写好了,十分详细,不多解释直接上代码 先让大家看看效果如何,具体操作还有各种用法,可以参考help里面的选项卡,file菜单中可以实现一些简单的操作,换算菜单中也内置了一些操作。 时间仓促,没能内置很多模块,不过可扩展性强,实现简单,大家可以自己动手来实现一些自己想要的功能。 大家可以去查看我博客里面的下载内容,有关于这个计算机程序

SitePoint播客即将来到WordCamp Raleigh进行特别现场表演-爱代码爱编程

We’re pleased to announce that the SitePoint Podcast is coming to WordCamp Raleigh for its first ever in person, live show, with special guests and over $1,500 in prizes for WordC