目录

简介

运行效果

代码

客户端

服务器

自定义库

通讯协议及相关配置定义库(DY.py)

数据库调用库(SJK.py)

套接字库(TJZ.py)

套接字通讯库(服务器端)(TJZ_FZ.py)


简介

一个用python写简易的聊天室程序,拥有登录、注册、找回密码、聊天功能,采用TPC通讯,无管理员功能,修改密码功能。代码正常运行需要安装Mysql数据库,请在代码前在Mysql数据库中创建一个用户,用户名为:root   密码为:123456。代码含详细注释,在此就不多赘述

运行效果

代码

客户端

调用自定义库DY.py

import socket
from DY import *
import tkinter as tk
from tkinter.scrolledtext import ScrolledText
import threading
import sys#创建窗口
class talkroom_system(object):def __init__(self):#窗口模块self.tk=tk#将相应函数放入字典(窗口函数调用)self.msg_denglu={}self.room_all={START_login:self.room_denglu,START_zhuce:self.room_zhuce,START_zh:self.room_zhaohui,START_zh_end:self.room_zhaohui_end,START_talk:self.room_laitian,START_zh_ok:self.room_get}#参数self.i=0self.n=0#将不同函数与相对应的命令一一对应self.next_step={START_login:{START_login_yes:self.room_change,START_login_no:self.denglu_fail},START_zhuce:{START_zhuce_yes:self.zhuce_result,START_zhuce_no:self.zhuce_result},START_zh:{START_n_yes:self.room_change,START_n_no:self.zh_name_no}}#数据存储self.user_self=[]self.user_qaa=[]#连接服务器def connecting(self):connect_room=self.tk.Tk()connect_room.title(TITLE)connect_room.geometry("500x120+500+270")lb_connect=self.tk.Label(connect_room,text='连接失败.........',font=('黑体',20)).place(x=50,y=40,width=400,height=30)#尝试连接while self.i==0:try:self.TJZ=socket.socket(socket.AF_INET,socket.SOCK_STREAM)self.TJZ.connect((MASTER_IP,9999))self.i=1connect_room.destroy()except:print('连接中...')self.n+=1if self.n==10:connect_room.mainloop()sys.exit()    #启动登录窗口self.room_denglu()#登录窗口def room_denglu(self):#窗口建立denglu_room=self.tk.Tk()denglu_room.title(TITLE)denglu_room.geometry("500x210+500+270")#文本设置lb_name=self.tk.Label(denglu_room,text='用户名').place(x=50,y=40,width=50,height=30)lb_mm=self.tk.Label(denglu_room,text='密码').place(x=50,y=90,width=50,height=30)#输入框tt_name=self.tk.Entry(denglu_room)tt_name.place(x=110,y=40,width=300,height=30)tt_mm=self.tk.Entry(denglu_room)tt_mm.place(x=110,y=90,width=300,height=30)data_denglu=[START_login,tt_name,tt_mm]#按钮设置bn_denglu=self.tk.Button(denglu_room,text='登录',command=lambda: self.msg_get(data_denglu,denglu_room))bn_denglu.place(x=125,y=150,width=100,height=30)bn_zhuce=self.tk.Button(denglu_room,text='注册',command=lambda:self.room_change(denglu_room,START_zhuce)).place(x=275,y=150,width=100,height=30)bn_zhaohui=self.tk.Button(denglu_room,text='找回密码',command=lambda:self.room_change(denglu_room,START_zh)).place(x=370,y=125,width=50,height=20)#保持窗口denglu_room.mainloop()#注册窗口def room_zhuce(self):#创建窗口zhuce_room=self.tk.Tk()zhuce_room.title(TITLE)zhuce_room.geometry("500x350+500+270")#文本显示lb_name=self.tk.Label(zhuce_room,text='用户名').place(x=50,y=40,width=50,height=30)lb_mm=self.tk.Label(zhuce_room,text='密码').place(x=50,y=90,width=50,height=30)lb_mm=self.tk.Label(zhuce_room,text='再次输入密码').place(x=50,y=140,width=50,height=30)lb_mm=self.tk.Label(zhuce_room,text='问题').place(x=50,y=190,width=50,height=30)lb_mm=self.tk.Label(zhuce_room,text='答案').place(x=50,y=240,width=50,height=30)#输入框tt_name=self.tk.Entry(zhuce_room)tt_name.place(x=110,y=40,width=300,height=30)tt_mm_1=self.tk.Entry(zhuce_room)tt_mm_1.place(x=110,y=90,width=300,height=30)tt_mm_2=self.tk.Entry(zhuce_room)tt_mm_2.place(x=110,y=140,width=300,height=30)tt_question=self.tk.Entry(zhuce_room)tt_question.place(x=110,y=190,width=300,height=30)tt_answer=self.tk.Entry(zhuce_room)tt_answer.place(x=110,y=240,width=300,height=30)#按钮设置data_zhuce=[START_zhuce,tt_name,tt_mm_1,tt_mm_2,tt_question,tt_answer]bn_yes=self.tk.Button(zhuce_room,text='确认',command=lambda:self.msg_get(data_zhuce,zhuce_room))bn_yes.place(x=320,y=290,width=100,height=30)#保持窗口zhuce_room.mainloop()#找回窗口1def room_zhaohui(self):#建立窗口zhaohui_room=self.tk.Tk()zhaohui_room.title(TITLE)zhaohui_room.geometry("500x120+500+270")#文本显示lb_name=self.tk.Label(zhaohui_room,text='用户名').place(x=50,y=40,width=50,height=30)#输入框tt_name=self.tk.Entry(zhaohui_room)tt_name.place(x=110,y=40,width=300,height=30)#按钮设置data=[START_zh,tt_name]bn_yes=self.tk.Button(zhaohui_room,text='确认',command=lambda:self.msg_get(data,zhaohui_room))bn_yes.place(x=350,y=80,width=90,height=28)#保持窗口zhaohui_room.mainloop()#找回窗口2def room_zhaohui_end(self):#建立窗口zh_end_room=self.tk.Tk()zh_end_room.title(TITLE) zh_end_room.geometry("500x120+500+270")#文本显示qst='问题:'+str(self.user_qaa[3])lb_qst=self.tk.Label(zh_end_room,text=qst,justify='left').place(x=-62,y=20,width=300,height=20)lb_ans=self.tk.Label(zh_end_room,text='答案').place(x=50,y=40,width=50,height=30)#输入框tt_ans=self.tk.Entry(zh_end_room)tt_ans.place(x=110,y=40,width=300,height=30)#按钮设置data=[START_zh_end,tt_ans]bn_yes=self.tk.Button(zh_end_room,text='确认',command=lambda:self.msg_get(data,zh_end_room))bn_yes.place(x=350,y=80,width=90,height=28)#保持窗口zh_end_room.mainloop()#找回成功窗口def room_get(self):#建立窗口zh_end_room=self.tk.Tk()zh_end_room.title(TITLE) zh_end_room.geometry("500x120+500+270")#文本显示qst='用户名:'+self.user_qaa[0]ans='密码:'+self.user_qaa[1]lb_qst=self.tk.Label(zh_end_room,text=qst,font=('黑体',20))lb_qst.place(x=0,y=20,width=300,height=30)lb_ans=self.tk.Label(zh_end_room,text=ans,font=('黑体',20))lb_ans.place(x=0,y=50,width=300,height=30)#按钮设置bn_yes=self.tk.Button(zh_end_room,text='返回',command=lambda:self.room_change(zh_end_room,START_login))bn_yes.place(x=350,y=80,width=90,height=28)#保持窗口zh_end_room.mainloop()#聊天室def room_laitian(self):#窗口初始化liaotian_room=self.tk.Tk()liaotian_room.title(TITLE)liaotian_room.geometry("750x450+400+180")#滚动文本聊天框tt_sc=ScrolledText(liaotian_room,font=('黑体',12))tt_sc.place(x=0,y=0,width=600,height=350)tt_sc.tag_config('tag1', foreground='blue')tt_sc.insert(self.tk.END, '欢迎进入群聊,大家开始聊天吧!', 'tag1')shuru=self.tk.StringVar()shuru.set('')#输入框tt_sr=self.tk.Entry(liaotian_room,textvariable=shuru,font=('黑体',12))tt_sr.place(x=0,y=350,width=600,height=100)#列表框tt_user=self.tk.Listbox(liaotian_room)tt_user.place(x=600,y=0,width=150,height=350)#按钮设置bt_sr=self.tk.Button(liaotian_room,text='发送',font=('黑体',20),command=lambda:self.msg_send(tt_sr,shuru))bt_sr.place(x=600,y=350,width=150,height=100)self.dxc_start(tt_sc,tt_user)#保持窗口liaotian_room.mainloop()#获取信息def msg_get(self,data,room):#分割信息check=0msg_get_ls=[]for i in data:try:msg_get_ls.append(i.get())except:msg_get_ls.append(i)#判断个别进程选项if msg_get_ls[0]==START_zhuce:if msg_get_ls[2]==msg_get_ls[3]:del msg_get_ls[2]else:lb_fail=self.tk.Label(room,text='两次输入密码不同!!!',justify='left',).place(x=80,y=270,width=200,height=20)check=1elif msg_get_ls[0]==START_zh_end:if msg_get_ls[1]==self.user_qaa[3]:self.room_change(room,START_zh_ok)check=1else:lb_fail=self.tk.Label(room,text='答案错误!!!',justify='left',).place(x=50,y=70,width=200,height=20)check=1#进入所匹配函数if check==0:self.msg_use(msg_get_ls,room)#窗口跳转def room_change(self,room_now,room):room_now.destroy()room_next=self.room_all[room]try:room_next()except:return#使用信息def msg_use(self,data_end,room):#判断传递信息类型,按协议处理数据if data_end[0]==START_login:self.user_self.append(data_end[1])msg_send=data_end[0]+SHOW_differ+data_end[1]+SHOW_differ+data_end[2]elif data_end[0]==START_zhuce:msg_send=data_end[0]+SHOW_differ+data_end[1]+SHOW_differ+data_end[2]+SHOW_differ+data_end[3]+SHOW_differ+data_end[4]elif data_end[0]==START_zh:msg_send=data_end[0]+SHOW_differ+data_end[1]#编码数据信息并发送至服务器self.TJZ.send(msg_send.encode(SHOW_change))recv_data=self.TJZ.recv(256).decode(SHOW_change)self.msg_recv(data_end[0],recv_data,room)#返回数据处理def msg_recv(self,request,recv_datas,room):#分割数据信息datas=recv_datas.split(SHOW_differ)recv_data=datas[0]next_step=self.next_step[request][recv_data]#判断信息类型并处理信息#登录成功if recv_data==START_login_yes:next_step(room,START_talk)msg_end=START_leaveself.TJZ.send(msg_end.encode(SHOW_change))#登录失败elif recv_data==START_login_no:next_step(room)del self.user_self[0]#注册成功elif recv_data==START_zhuce_yes:next_step(recv_data,room)self.room_change(room,START_login)#注册失败elif recv_data==START_zhuce_no:next_step(recv_data,room)#找回用户名存在elif recv_data==START_n_yes:self.user_qaa.append(datas[1])self.user_qaa.append(datas[2])self.user_qaa.append(datas[3])self.user_qaa.append(datas[4])next_step(room,START_zh_end)#找回用户名不存在elif recv_data==START_n_no:next_step(room)#登录失败def denglu_fail(self,room):lb_fail=self.tk.Label(room,text='用户名或密码错误!!!',justify='left',).place(x=80,y=120,width=200,height=20)#注册结果def zhuce_result(self,result,room):if result==START_zhuce_yes:lb_fail=self.tk.Label(room,text='注册成功!!!',justify='left',).place(x=80,y=270,width=200,height=20)elif result==START_zhuce_no:lb_fail=self.tk.Label(room,text='用户名已存在!!!',justify='left',).place(x=80,y=270,width=200,height=20)#找回失败1def zh_name_no(self,room):lb_fail=self.tk.Label(room,text='用户名不存在!!!',justify='left',).place(x=65,y=70,width=200,height=20)#发送聊天消息def msg_send(self,tt_sr,shuru):msg_get=START_talk+SHOW_differ+self.user_self[0]+SHOW_differ+tt_sr.get()self.TJZ.send(msg_get.encode(SHOW_change))shuru.set('')#处理接受的与聊天相关的消息def msg_last(self,tt_sc,tt_user):#解码信息msg_new=self.TJZ.recv(256).decode(SHOW_change)#分割信息msg_chuli=msg_new.split(SHOW_differ)#判断聊天信息类型#用户列表if msg_chuli[0]==START_talk_users:tt_user.delete(0,self.tk.END)for i in range(1,len(msg_chuli)):tt_user.insert(self.tk.END,msg_chuli[i])#聊天信息elif msg_chuli[0]==START_talk_msg:user_name=msg_chuli[1]user_msg=msg_chuli[2]if user_name==self.user_self[0]:user_name=USER_selfmsg_last=user_name+':'+user_msgtt_sc.insert(self.tk.INSERT,'\n')tt_sc.insert(self.tk.END,msg_last)#新用户进入聊天室elif msg_chuli[0]==START_user_in:msg_last=msg_chuli[1]+'进入了聊天室....'tt_sc.insert(self.tk.INSERT,'\n')tt_sc.insert(self.tk.END,msg_last)#客户端离线elif msg_chuli[0]==START_leave_yes:sys.exit()#多线程准备def chixu(self,tt_sc,tt_user):try:while True:self.msg_last(tt_sc,tt_user)except:sys.exit()#多线程def dxc_start(self,tt_sc,tt_user):self.T = threading.Thread(target=lambda:self.chixu(tt_sc,tt_user))  # 多线程self.T.start() # 启动#主程序
if __name__=='__main__':talkroom_system().connecting()

服务器

调用自定义库TJZ.py、TJZ_FZ.py、SJK.py、DY.py

from TJZ import ServerSocket
from TJZ_FZ import Socket_dabao
from threading import Thread
from DY import *
from SJK import mysql_use#服务器核心模块
class Server(object):def __init__(self):#套接字self.TJZ=ServerSocket()#数据库self.SJK=mysql_use()self.SJK.create_kb()self.message_all=self.SJK.message_get()#在线人数self.user_online={}self.number=1#处理响应不同功能self.SJ_differ={}self.chuli_sjlx(START_zhuce,self.request_zhuce)self.chuli_sjlx(START_login,self.request_denglu)self.chuli_sjlx(START_talk,self.request_talk)self.chuli_sjlx(START_zh,self.request_zh_name)#将函数装入字典def chuli_sjlx(self,request,gongneng):self.SJ_differ[request]=gongneng#等待客户端连接def starting(self):while True:#获取客户端连接soc,addr =self.TJZ.accept()#封装对象KHD_soc=Socket_dabao(soc)#传递信息(多线程进行)Thread(target=lambda:self.ZXC_msg(KHD_soc)).start()#接受信息并解码def ZXC_msg(self,KHD_soc):  while True:#获取数据recv_data=KHD_soc.recv_data()if  recv_data==START_leave or recv_data=='':#关闭客户端套接字self.user_offline(KHD_soc)KHD_soc.close()break#解码数据KHD_msg_jm=self.shuju_jiema(recv_data)gongneng=self.SJ_differ.get(KHD_msg_jm['request'])#调用相应函数if gongneng:gongneng(KHD_msg_jm,KHD_soc)#离线处理def user_offline(self,KHD_soc):#发送允许下线回应KHD_soc.send_data(START_leave_yes)#如果存在其他用户,告知新的在线用户列表try:for name,message_person in self.user_online.items():if message_person['soc']==KHD_soc:#制作新的用户列表self.user_online.pop(name)users_all=''for name,message_person in self.user_online.items():user_lingshi1=message_person['name_user']user_lingshi2=users_allusers_all=user_lingshi2+SHOW_differ+user_lingshi1msg_sendto=START_talk_users+users_all#发送至所以在线客户端for name,message_person in self.user_online.items():KHD_soc.send_data(START_login_yes)message_person['soc'].send_data(msg_sendto)#如果不存在其他在线用户except:return#处理数据def shuju_jiema(self,revc_data):#分割信息recv_list=revc_data.split(SHOW_differ)#将分割好的数据存入字典data_chuli={}data_chuli['request']=recv_list[0]if data_chuli['request']==START_zhuce:data_chuli['name_user']=recv_list[1]data_chuli['password']=recv_list[2]data_chuli['question']=recv_list[3]data_chuli['answer']=recv_list[4]elif data_chuli['request']==START_login:data_chuli['name_user']=recv_list[1]data_chuli['password']=recv_list[2]elif data_chuli['request']==START_talk:data_chuli['name_user']=recv_list[1]data_chuli['message']=recv_list[2]elif data_chuli['request']==START_zh:data_chuli['name_user']=recv_list[1]  #返回数据字典  return data_chuli#注册响应def request_zhuce(self,data_chuli,KHD_soc):#注册参数check=1#注册用户数据lingshi=[data_chuli['name_user'],data_chuli['password'],data_chuli['question'],data_chuli['answer']]data=tuple(lingshi)#判断用户名是否重复for i in self.message_all:if lingshi[0]==i[0] :check=2#注册失败KHD_soc.send_data(START_zhuce_no)#注册成功if check==1:#更新数据库用户信息self.SJK.message_add(data)KHD_soc.send_data(START_zhuce_yes)#获取新的数据库用户信息self.message_all=self.SJK.message_get()#登录响应def request_denglu(self,data_chuli,KHD_soc):#登录参数check=1#登录用户信息list_lingshi=[data_chuli['name_user'],data_chuli['password']]#判断用户信息是否正确for i in self.message_all:#登陆成功if list_lingshi[0]==i[0] and list_lingshi[1]==i[1]:check=2#加入在线用户字典self.user_online[list_lingshi[0]]={'soc':KHD_soc,'name_user':list_lingshi[0]}#制作用户列表数据users_all=''for name,message_person in self.user_online.items():user_lingshi1=message_person['name_user']user_lingshi2=users_allusers_all=user_lingshi2+SHOW_differ+user_lingshi1msg_sendto=START_talk_users+users_all#登录成功请求恢复KHD_soc.send_data(START_login_yes)self.number+=1user_in=START_user_in+SHOW_differ+list_lingshi[0]if self.number>len(self.user_online):#更新客户端用户列表for name,message_person in self.user_online.items():message_person['soc'].send_data(msg_sendto)#告知在线客户端新用户登录for name,message_person in self.user_online.items():if message_person['name_user']!=list_lingshi[0]:message_person['soc'].send_data(user_in)#登陆失败if check==1:KHD_soc.send_data(START_login_no)#找回响应def request_zh_name(self,data_chuli,KHD_soc):#找回参数check=1list_lingshi=[data_chuli['name_user']]#判断找回用户是否存在for i in self.message_all:#存在该用户,返回数据信息if list_lingshi[0]==i[0] :check=2qaa=START_n_yes+SHOW_differ+i[0]+SHOW_differ+i[1]+SHOW_differ+i[2]+SHOW_differ+i[3]KHD_soc.send_data(qaa)#不存在该用户if check==1:KHD_soc.send_data(START_n_no)#聊天响应def request_talk(self,data_chuli,KHD_soc):#根据协议制作聊天信息list_lingshi=[data_chuli['name_user'],data_chuli['message']]msg=START_talk_msg +SHOW_differ+list_lingshi[0]+SHOW_differ+list_lingshi[1]#转发至所有在线客户端for name,message_person in self.user_online.items():message_person['soc'].send_data(msg)#测试程序
if __name__=='__main__':Server().starting()

自定义库

通讯协议及相关配置定义库(DY.py)

#数据协议相关配置
START_zhuce='zhuce'#注册请求
START_login='denglu'#登录请求
START_talk='liaotian'#聊天请求
START_zh='zhaohui'#找回请求
START_leave='end_user'#离线请求
START_user_in='user_in'#用户加入聊天室
START_zhuce_yes='zhuce_yes'#注册请求响应1
START_zhuce_no='zhuce_no'#注册请求响应2
START_login_yes='denglu_yes'#登录结果响应1
START_login_no='denglu_no'#登录结果响应2
START_talk_msg='msg'#聊天响应1
START_talk_users='users'#聊天响应2
START_n_yes='name_yes'#找回响应1
START_n_no='name_no'#找回响应2
START_zh_end='zh_end'#找回响应3
START_zh_ok='zh_yes'#找回响应4
START_leave_yes='xiaxian'#离线响应
SHOW_differ='+-+'#自定义协议分割符
SHOW_change='utf-8'#编码解码方式#标题
TITLE='简易聊天室'#用户自称
USER_self='我'#服务器数据配置
MASTER_IP='127.0.0.1'
MASTER_PORT=9999

数据库调用库(SJK.py)

import pymysqlclass mysql_use(object):def __init__(self):self.sjk=pymysql.connect(host='127.0.0.1',user='root',password='123456')self.use_sjk=self.sjk.cursor()self.jk='CREATE DATABASE IF NOT EXISTS FWQ'self.use_k='use FWQ'self.jb= """CREATE TABLE IF NOT EXISTS user_message(name_user varchar(50) NOT NULL,password varchar(50) NOT NULL,question varchar(50) NOT NULL,answer varchar(50) NOT NULL,PRIMARY KEY (name_user)   ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;"""#建库建表def create_kb(self):# 创建库和表 self.use_sjk.execute(self.jk)try:self.use_sjk.execute(self.use_k)self.use_sjk.execexcept:return#添加用户信息def message_add(self,user_data):self.use_sjk.execute(self.use_k)#输入数据self.use_sjk.execute("insert into user_message(name_user,password,question,answer) values (%s,%s,%s,%s)",user_data)#上传数据self.sjk.commit()#获取用户数据def message_get(self):self.use_sjk.execute(self.use_k)self.use_sjk.execute("SELECT * FROM user_message")user_data=self.use_sjk.fetchall()data=[]for i in user_data:lingshi=[]lingshi.append(i[0])lingshi.append(i[1])lingshi.append(i[2])lingshi.append(i[3])data.append(lingshi)return data#关闭数据库def sjk_close(self):self.use_sjk.close()self.sjk.close()

套接字库(TJZ.py)

import socket
from DY import *#自定义套接字,初始化服务器套接字的相关参数
class ServerSocket(socket.socket):def __init__(self):#设置为TCP类型super(ServerSocket,self).__init__(socket.AF_INET,socket.SOCK_STREAM)#绑定地址和端口self.bind((MASTER_IP,MASTER_PORT))#设置为监听模式self.listen(100)

套接字通讯库(服务器端)(TJZ_FZ.py)

#封装套接字
class Socket_dabao(object):def __init__(self,soc):self.soc=soc#接收数据并解码def recv_data(self):try:return self.soc.recv(256).decode('utf-8')except:return ''             #发送编码数据def send_data(self,message):return self.soc.send(message.encode('utf-8'))#关闭链接def close(self):self.soc.close()

简易聊天室(Python版)相关推荐

  1. Express+Socket.IO 实现简易聊天室

    代码地址如下: http://www.demodashi.com/demo/12477.html 闲暇之余研究了一下 Socket.io,搭建了一个简易版的聊天室,如有不对之处还望指正,先上效果图: ...

  2. 连夜撸了一个简易聊天室

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 分不清轮询.长轮询?不知道什么时候该用websocket还 ...

  3. 撸一个简易聊天室,不信你学不会实时消息推送(附源码)

    点击上方 好好学java ,选择 星标 公众号重磅资讯,干货,第一时间送达 今日推荐:推荐 19 个 github 超牛逼项目!个人原创100W +访问量博客:点击前往,查看更多 分不清轮询.长轮询? ...

  4. java聊天室程序_Java简易聊天室程序socket

    Java简易聊天室程序socket chatroomdemo.java package com.socket.demo; import java.io.IOException; import java ...

  5. JavaSE项目之聊天室swing版

    引子: 当前,互联网 体系结构的参考模型主要有两种,一种是OSI参考模型,另一种是TCP/IP参考模型. 一.OSI参考模型,即开放式通信系统互联参考模型(OSI/RM,Open Systems In ...

  6. Socket编程实现简易聊天室

    1.Socket基础知识 Socket(套接字)用于描述IP地址和端口,是通信链的句柄,应用程序可以通过Socket向网络发出请求或者应答网络请求. Socket是支持TCP/IP协议的网络通信的基本 ...

  7. 基于Node.js + WebSocket 的简易聊天室

    代码地址如下: http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.j ...

  8. docker搭建swoole简易聊天室

    docker搭建swoole的简易聊天室 首先pull镜像 docker pull docker.io/kong36088/nginx-php7-swoole 创建容器 docker run --na ...

  9. Java WebSocket编程与网页简易聊天室

    在webSocket还未引入前,许多开发人员通过各种非正规手段来完成更新网站的最新信息和到所有当前访问者的任务,其中一种手段就是通过浏览器向服务器轮询更新,但这种手段的网络延迟比较明显,其用户体验比较 ...

最新文章

  1. AI顶会组团“改版”:NeurIPS 2020宣布deadline延期三周
  2. Django实战之添加markdown编写文章的支持
  3. 通过AI技术研究网红对其粉丝的消费品牌意识的影响
  4. 鲁迅散文——狗的驳诘
  5. linux 提取cpio_使用rpm2cpio,cpio提取rpm包的中的特定文件
  6. .NET Core 给使用.NET的公司所带来的机遇
  7. 安卓手机背景变黑色怎么改_别着急扔掉旧手机 你的电脑可能需要它
  8. html标签object和embed,html标签object和embed的区别
  9. 【将图像字符画】【第二玩】图像字符化
  10. js获取字符串的字节数
  11. mysql服务器级别角色_服务器数据库系列 - MySQL事务隔离级别详解
  12. 裁剪并获取固定大小的图片
  13. jdk list接口源码解析
  14. DIV+CSS两种盒子模型
  15. python实现三级菜单
  16. 移动U盘数据恢复,移动U盘数据恢复方法
  17. excel服务器模板修改,勤哲Excel服务器设计查询模板
  18. 漏洞扫描工具之nessus
  19. Velero备份实战 - 基于Ceph的CSI快照
  20. 数字电子技术《优先编码器74LS148》仿真

热门文章

  1. Android下使用JDBC连接Mysql实现创建账号
  2. Baojing Gu
  3. 持续集成学习笔记-入门篇(1)持续集成基本概念
  4. 软件测试面试:电梯测试用例怎么写
  5. 文本框时间为日历格式
  6. 在使用evo进行orb-slam2轨迹评估时提示时间戳没有对齐的问题
  7. 部署TVM Runtime
  8. PhysX3.4文档(8) -- Advanced Collision Detection
  9. 高德js版地图在iOS15 beta版本卡死的问题
  10. Opencv cvCircle()函数