Python聊天室2.0隆重推出!!!!
一.前言
12月22日,我提出了一个想法,那就是实现Python聊天室!
一开始我觉得很难,毕竟我从未接接触过用python编写关于网络的东西
于是我就在网上发帖求助,也遇到了许多帮助
时隔(好像是9天吧)我终于做出了一个“残缺”的程序( )
二.整体思路
整体思路是用python的socket模块,与我的服务器进行连接,然后服务端把一个用户发送的内容再发送到每一个用户手上,就实现了群聊。
想要更多思路的可以私信我{:10_281:}
三.程序内容
该程序实现了群聊在线列表登陆验证
等基本功能
接下来的版本会实现数据传输加密客户端哈希值验证程序自毁功能表情包发送图片发送
已知问题当注册不成功时,只能强制退出待机久了会掉线(我是这样,别人没有遇到)
这也就当测试版看看吧{:10_256:}
四.程序运行截图
五.程序源码
客户端:
Mac版:[ol]from tkinter import *from tkinter.font import Font# from tkinter.ttk import *from tkinter import messagebox as mgimport timeimport threadingimport socketdef center_window(root, width, height): """ 窗口居中代码 """ screenwidth = root.winfo_screenwidth() # 获取显示屏宽度 screenheight = root.winfo_screenheight() # 获取显示屏高度 size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) # 设置窗口居中参数 root.geometry(size) # 让窗口居中显示def fasong(*args): time.sleep(0.1) # re_data = input(">>") re_data = send_entry.get("1.0", END)[:-1] if 'exit' == re_data: # 判断是否退出 client.send(("Q "+ username).encode()) # 发送退出的请求 client.close() elif (re_data != " \n" and re_data != "\n" and re_data != "" and re_data != " "): # 判断内容不为空 client.send(("C " + username + ": " + re_data).encode()) time_ = time.strftime('%Y-%m-%d %H:%M:%S') # 以下为自己说的话 chat_text.config(state=NORMAL) f1 = Font(size=10) chat_text.tag_config("tag_3", font=f1, foreground="grey") chat_text.insert(END, time_, "tag_3") # 发送时间 chat_text.insert(END, "\n") f = Font(size=15) chat_text.tag_config("tag_41", font=f, foreground="#808080") chat_text.insert(END, username + ":", "tag_41") # 发送文本内容 chat_text.insert(END, "\n") f = Font(size=14) chat_text.tag_config("tag_4", font=f, foreground="#2E8B57") chat_text.insert(END, re_data, "tag_4") # 发送文本内容 chat_text.insert(END, "\n") chat_text.config(state=DISABLED) chat_text.see("end") # 转到最后一行 # send_entry.first() # send_entry.delete(0.1,2.0) # 设置发送为空 # send_entry.insert('1 wordstart' , "s") # time.sleep(0.1) send_entry.delete("0.0", END) # 设置发送为空def fa_(*args): fasong() # send_entry.delete("0.0", END) # 设置发送为空 return 'break'def jieshou(): while True: # time.sleep(0.3) try: data = client.recv(1024) res = data.decode() if(res != ''): # print("1") if (res.split(" ", 2)[0]=="C"): # 如果为聊天的请求 # print(res.split(" ", 1)[0]) # print(res.split(" ", 1)[1]) # print(res) time_ = time.strftime('%Y-%m-%d %H:%M:%S') chat_text.config(state=NORMAL) f1 = Font(size=10) chat_text.tag_config("tag_1", font=f1, foreground="grey") chat_text.insert(END, time_, "tag_1") chat_text.insert(END, "\n") f = Font(size=15) chat_text.tag_config("tag", font=f, foreground="#808080") chat_text.insert(END, res.split(" ", 2)[1], "tag") chat_text.insert(END, "\n") f = Font(size=14) chat_text.tag_config("tag_2", font=f) chat_text.insert(END, res.split(" ", 2)[2], "tag_2") chat_text.insert(END, "\n") chat_text.config(state=DISABLED) chat_text.see("end") elif(res.split(" ", 1)[0]=="R"): # 在线用户请求 afd = False print(res.split(" ", 1)[1]) for kk in range(0, online_user.size()): # 循环判断在线列表里是否有用户名 if online_user.get(kk) == (res.split(" ", 1)[1]): # 检测到是 afd = True # 判断变量为真 break # 退出 if (afd == False): # 如果判断变量为假 online_user.insert(END,res.split(" ", 1)[1]) # 插入用户名 elif(res.split(" ", 1)[0]=="E"): # 退出请求 for kk in range(0, online_user.size()): # 循环判断要删除的用户名 if online_user.get(kk) == (res.split(" ", 1)[1]): online_user.delete(kk) # 从在线列表去除 break # else: # continue except Exception as e: print(e) print("客户端已退出") #breakdef send(): """ 发送文字 """ global username username = username_string.get() # 用户名变量 # time.sleep(3) if __name__ == "__main__": # print("Welcome to Gouzi WD Chat") # print(username) #注册业务 while True: # username=input("请输入用户名") if ' ' not in username and username != " " and username != "": # 判断用户名不为空 client.send(("R "+username + " " + password_string.get()+"\n").encode()) # 发送注册请求 data=client.recv(2048).decode() # 最大接受字节 if data=="OK": # 如果穿回信息为 “OK” break else: mg.showerror("", "用户名不能为空,请强制退出后重新进入") # 用户名如果为空,发出警告 try: # 创建一个新的线程 new_thread = threading.Thread(target=jieshou, name="T1") # 启动新线程 new_thread.start() new_thread1 = threading.Thread(target=fasong, name="T2") # 启动新线程 new_thread1.start() except: client.close()def insert_newline(*args): send_entry.insert("insert", "\n") return "break"def main(): """ 加入聊天后界面 """ global chat_text, send_msg, online_user, send_entry root = Toplevel() root.title("聊天界面") center_window(root, 800, 500) send_msg = StringVar() """ —————————————————————————— 查收文件text开始 """ frame = Frame(root) frame.place(x = 20, y = 20) gun_song_tiao_y = Scrollbar(frame) gun_song_tiao_x = Scrollbar(frame, orient=HORIZONTAL) chat_text = Text(frame, height=20, width=60, wrap='none', relief=GROOVE, state=DISABLED, font=('微软雅黑', 14))#, state=DISABLED gun_song_tiao_y.pack(side=RIGHT,fill=Y) gun_song_tiao_x.pack(side=BOTTOM, fill=X) chat_text.pack() gun_song_tiao_y.config(command=chat_text.yview) gun_song_tiao_x.config(command=chat_text.xview) chat_text.config(yscrollcommand=gun_song_tiao_y.set) chat_text.config(xscrollcommand=gun_song_tiao_x.set) """ 查收文件区域text结束 —————————————————————————— """ send_entry = Text(root, width=70, height=6) # 发送区域 send_entry.place(x=20, y=390) send_button = Button(root, text="发送", command=fa_) # 发送按钮 send_button.place(x=520, y=390) send_entry.bind("", fa_) send_entry.bind("", insert_newline) Label(root, text="在线列表", font=("微软雅黑", 18)).place(x=600, y=20) online_user = Listbox(root, height=25) online_user.place(x=600, y=50) # online_user.insert(END, username_string.get())def help(): """ 帮助界面 """ mg.showerror("暂无", "NONE")def if_login(*args): main() send()def if_res(): passdef login(): """注册/登陆""" global username_string global username_string, password_string global client root = Tk() center_window(root, 400, 300) # 实现页面居中 root.title("Gouzi WD在线聊天室") # 标题 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('43.138.0.102', 80)) username_string = StringVar() # 存储用户名变量 password_string = StringVar() # 密码存储变量 Label(root, text="登陆界面", font=("微软雅黑", 20)).place(x=130, y=30) # 表头 Label(root, text="用户名:", font=("微软雅黑", 14)).place(x=10, y=100) # 用户名一栏 username = Entry(root, textvariable=username_string) #用户名Entry username.place(x=110, y=100) Label(root, text="密码:", font=("微软雅黑", 14)).place(x=10, y=150) # 密码一栏 password = Entry(root, textvariable=password_string, show="*") # 密码Entry password.place(x=110, y=150) username.bind("", if_login) password.bind("", if_login) join_button = Button(root, text="登陆", command=if_login, font=("微软雅黑", 12)) # 进入聊天界面按钮 join_button.place(x=60, y=200) res_button = Button(root, text="注册", command=if_res, font=("微软雅黑", 12)) # 注册 res_button.place(x=230, y=200) # if_login() root.mainloop()login()# def login(): # """# 登陆界面,也是初始界面# """# root = Tk()# center_window(root, 400, 500) # 实现页面居中# root.title("Gouzi WD在线聊天室") # 标题# username_string = StringVar() # 存储用户名变量# ip_string = StringVar() # ip存储变量# password_string = StringVar() # 密码存储变量# Label(root, text="初始界面", font=("微软雅黑", 20)).place(x=130, y=30) # 表头# Label(root, text="用户名:", font=("微软雅黑", 14)).place(x=10, y=100) # 用户名一栏# username = Entry(root, textvariable=username_string) #用户名Entry# username.place(x=110, y=100)# Label(root, text="ip:", font=("微软雅黑", 14)).place(x=10, y=150) # ip一栏# ip = Entry(root, textvariable=ip_string) #ipEntry# ip.place(x=110, y=150)# Label(root, text="ip密码(选填):", font=("微软雅黑", 14)).place(x=10, y=200) # 密码一栏# password = Entry(root, textvariable=password_string) # 密码Entry# password.place(x=110, y=200)# Label(root, text="预留位:", font=("微软雅黑", 14)).place(x=10, y=250) # 预留一栏# password = Entry(root) # 预留Entry# password.place(x=110, y=250)# join_button = Button(root, text="进入", command=join, font=("微软雅黑", 12)) # 进入聊天界面按钮# join_button.place(x=160, y=300)# help_button = Button(root, text="帮助", font=("微软雅黑", 9), command=help) # 帮助按钮# help_button.place(x=163, y=350)# # join()# root.mainloop()Windows版:[code]from tkinter import *from tkinter.font import Font# from tkinter.ttk import *from tkinter import messagebox as mgimport timeimport threadingimport socketdef center_window(root, width, height): """ 窗口居中代码 """ screenwidth = root.winfo_screenwidth() # 获取显示屏宽度 screenheight = root.winfo_screenheight() # 获取显示屏高度 size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) # 设置窗口居中参数 root.geometry(size) # 让窗口居中显示def fasong(*args): time.sleep(0.1) # re_data = input(">>") re_data = send_entry.get("1.0", END)[:-1] if 'exit' == re_data: # 判断是否退出 client.send(("Q "+ username).encode()) # 发送退出的请求 client.close() elif (re_data != " \n" and re_data != "\n" and re_data != "" and re_data != " "): # 判断内容不为空 client.send(("C " + username + ": " + re_data).encode()) time_ = time.strftime('%Y-%m-%d %H:%M:%S') # 以下为自己说的话 chat_text.config(state=NORMAL) #f1 = Font("微软雅黑", 8) chat_text.tag_config("tag_3", font=("微软雅黑", 9), foreground="grey") chat_text.insert(END, time_, "tag_3") # 发送时间 chat_text.insert(END, "\n") #f = Font("微软雅黑", 13) chat_text.tag_config("tag_41", font=("微软雅黑", 14), foreground="#808080") chat_text.insert(END, username + ":", "tag_41") # 发送文本内容 chat_text.insert(END, "\n") #f = Font("微软雅黑", 12) chat_text.tag_config("tag_4", font=("微软雅黑", 13), foreground="#2E8B57") chat_text.insert(END, re_data, "tag_4") # 发送文本内容 chat_text.insert(END, "\n") chat_text.config(state=DISABLED) chat_text.see("end") # 转到最后一行 # send_entry.first() # send_entry.delete(0.1,2.0) # 设置发送为空 # send_entry.insert('1 wordstart' , "s") # time.sleep(0.1) send_entry.delete("0.0", END) # 设置发送为空def fa_(*args): fasong() # send_entry.delete("0.0", END) # 设置发送为空 return 'break'def jieshou(): while True: # time.sleep(0.3) try: data = client.recv(1024) res = data.decode() if(res != ''): # print("1") if (res.split(" ", 2)[0]=="C"): # 如果为聊天的请求 # print(res.split(" ", 1)[0]) # print(res.split(" ", 1)[1]) # print(res) time_ = time.strftime('%Y-%m-%d %H:%M:%S') chat_text.config(state=NORMAL) #f1 = Font("微软雅黑", 10) chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey") chat_text.insert(END, time_, "tag_1") chat_text.insert(END, "\n") #f = Font("微软雅黑", 13) chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080") chat_text.insert(END, res.split(" ", 2)[1], "tag") chat_text.insert(END, "\n") #f = Font("微软雅黑", 12) chat_text.tag_config("tag_2", font=("微软雅黑", 13)) chat_text.insert(END, res.split(" ", 2)[2], "tag_2") chat_text.insert(END, "\n") chat_text.config(state=DISABLED) chat_text.see("end") elif(res.split(" ", 1)[0]=="R"): # 在线用户请求 afd = False print(res.split(" ", 1)[1]) for kk in range(0, online_user.size()): # 循环判断在线列表里是否有用户名 if online_user.get(kk) == (res.split(" ", 1)[1]): # 检测到是 afd = True # 判断变量为真 break # 退出 if (afd == False): # 如果判断变量为假 online_user.insert(END,res.split(" ", 1)[1]) # 插入用户名 elif(res.split(" ", 1)[0]=="E"): # 退出请求 for kk in range(0, online_user.size()): # 循环判断要删除的用户名 if online_user.get(kk) == (res.split(" ", 1)[1]): online_user.delete(kk) # 从在线列表去除 break # else: # continue except Exception as e: print(e) print("客户端已退出") #breakdef send(): """ 发送文字 """ global username username = username_string.get() # 用户名变量 # time.sleep(3) if __name__ == "__main__": # print("Welcome to Gouzi WD Chat") # print(username) #注册业务 while True: # username=input("请输入用户名") if ' ' not in username and username != " " and username != "": # 判断用户名不为空 client.send(("R "+username + " " + password_string.get()+"\n").encode()) # 发送注册请求 data=client.recv(2048).decode() # 最大接受字节 if data=="OK": # 如果穿回信息为 “OK” break else: mg.showerror("", "用户名不能为空,请强制退出后重新进入") # 用户名如果为空,发出警告 try: # 创建一个新的线程 new_thread = threading.Thread(target=jieshou, name="T1") # 启动新线程 new_thread.start() new_thread1 = threading.Thread(target=fasong, name="T2") # 启动新线程 new_thread1.start() except: client.close()def insert_newline(*args): send_entry.insert("insert", "\n") return "break"def main(): """ 加入聊天后界面 """ global chat_text, send_msg, online_user, send_entry root = Toplevel() root.title("聊天界面") center_window(root, 800, 500) send_msg = StringVar() """ —————————————————————————— 查收文件text开始 """ frame = Frame(root) frame.place(x = 20, y = 20) gun_song_tiao_y = Scrollbar(frame) gun_song_tiao_x = Scrollbar(frame, orient=HORIZONTAL) chat_text = Text(frame, height=14, width=50, wrap='none', relief=GROOVE, state=DISABLED, font=('微软雅黑', 14))#, state=DISABLED gun_song_tiao_y.pack(side=RIGHT,fill=Y) gun_song_tiao_x.pack(side=BOTTOM, fill=X) chat_text.pack() gun_song_tiao_y.config(command=chat_text.yview) gun_song_tiao_x.config(command=chat_text.xview) chat_text.config(yscrollcommand=gun_song_tiao_y.set) chat_text.config(xscrollcommand=gun_song_tiao_x.set) """ 查收文件区域text结束 —————————————————————————— """ send_entry = Text(root, width=70, height=6) # 发送区域 send_entry.place(x=20, y=390) send_button = Button(root, text="发送", command=fa_) # 发送按钮 send_button.place(x=520, y=390) send_entry.bind("", fa_) send_entry.bind("", insert_newline) Label(root, text="在线列表", font=("微软雅黑", 18)).place(x=600, y=20) online_user = Listbox(root, height=20) online_user.place(x=600, y=50) # online_user.insert(END, username_string.get())def help(): """ 帮助界面 """ mg.showerror("暂无", "NONE")def if_login(*args): main() send()def if_res(): passdef login(): """注册/登陆""" global username_string global username_string, password_string global client root = Tk() center_window(root, 400, 300) # 实现页面居中 root.title("Gouzi WD在线聊天室") # 标题 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('43.138.0.102', 80)) username_string = StringVar() # 存储用户名变量 password_string = StringVar() # 密码存储变量 Label(root, text="登陆界面", font=("微软雅黑", 20)).place(x=130, y=30) # 表头 Label(root, text="用户名:", font=("微软雅黑", 14)).place(x=10, y=100) # 用户名一栏 username = Entry(root, textvariable=username_string) #用户名Entry username.place(x=110, y=100) Label(root, text="密码:", font=("微软雅黑", 14)).place(x=10, y=150) # 密码一栏 password = Entry(root, textvariable=password_string) # 密码Entry password.place(x=110, y=150) username.bind("", if_login) password.bind("", if_login) join_button = Button(root, text="登陆", command=if_login, font=("微软雅黑", 12)) # 进入聊天界面按钮 join_button.place(x=60, y=200) res_button = Button(root, text="注册", command=if_res, font=("微软雅黑", 12)) # 注册 res_button.place(x=230, y=200) # if_login() root.mainloop()login()# def login(): # """# 登陆界面,也是初始界面# """# root = Tk()# center_window(root, 400, 500) # 实现页面居中# root.title("Gouzi WD在线聊天室") # 标题# username_string = StringVar() # 存储用户名变量# ip_string = StringVar() # ip存储变量# password_string = StringVar() # 密码存储变量# Label(root, text="初始界面", font=("微软雅黑", 20)).place(x=130, y=30) # 表头# Label(root, text="用户名:", font=("微软雅黑", 14)).place(x=10, y=100) # 用户名一栏# username = Entry(root, textvariable=username_string) #用户名Entry# username.place(x=110, y=100)# Label(root, text="ip:", font=("微软雅黑", 14)).place(x=10, y=150) # ip一栏# ip = Entry(root, textvariable=ip_string) #ipEntry# ip.place(x=110, y=150)# Label(root, text="ip密码(选填):", font=("微软雅黑", 14)).place(x=10, y=200) # 密码一栏# password = Entry(root, textvariable=password_string) # 密码Entry# password.place(x=110, y=200)# Label(root, text="预留位:", font=("微软雅黑", 14)).place(x=10, y=250) # 预留一栏# password = Entry(root) # 预留Entry# password.place(x=110, y=250)# join_button = Button(root, text="进入", command=join, font=("微软雅黑", 12)) # 进入聊天界面按钮# join_button.place(x=160, y=300)# help_button = Button(root, text="帮助", font=("微软雅黑", 9), command=help) # 帮助按钮# help_button.place(x=163, y=350)# # join()# root.mainloop()[/ol]复制代码四.服务端代码
[Python] 纯文本查看 复制代码from socket import *
import threading
import time
BUFLEN = 2048
user={}#储存用户信息
username = {}
# Note=open('后台记录.txt',mode='w')
def deal(dataSocket, addr):
while True:
time.sleep(0.3)
try:
recved = dataSocket.recv(BUFLEN) # 最大接收字节
info = recved.decode() # 接受的消息
# 如果返回空bytes,表示对方关闭了连接
# 退出循环,结束消息收发
if len(info)==0: # 如果接受的消息长度为0
#print("len=0")
for key, k in list(user.items()): # 便利user的键-值对 key为键, k为值
#处理用户意外断开
if k == dataSocket: # 如果便利到的值与当前连接的数据一致
#print(user[k])
del user[key] # 删除掉这个值
#print(user)
if key == "" or key == " ": # 如果key为空(为了预防用户名传来为空客户端的在线列表无法显示,所以将“ ”改为“空”)
for ka in user: # 遍历user,发送退出的消息
user[ka].send(("空" + "已退出群聊").encode())
user[ka].send(("E " + "空").encode()) # 传回用户名为“空”的退出了群聊
break
else: # 如果不为空
for ka in user: # 一样的操作,只不过是传回原本的用户名
user[ka].send((key + "已退出群聊").encode())
user[ka].send(("E " + key).encode())
break
#处理注册业务
elif info.split(' ',1)[0]=="R": # 如果请求为注册
user_text = open("./user_text.txt", mode="r")
lines = user_text.readlines()
if len(info.split(' ',2))==1: # 没看懂(
dataSocket.send("No".encode())
elif info.split(' ',2)[1] in user: # 如果这个用户名已经在user里了
dataSocket.send("No".encode()) # 拒接注册
elif " " in info.split(' ',2)[1] and " " in info.split(' ',2)[0]: # 如果用户名为空,拒绝注册(好像并没有起作用)
dataSocket.send("No".encode())
for user_len in range(0, len(lines)):
if (lines[user_len].split(" ", 1)[0] == info.split(' ',2)[1] and lines[user_len].split(" ", 1)[1] == info.split(' ',2)[2]):
if (info.split(' ',2)[1] == " " or info.split(' ',2)[1] == ""): # 如果用户名为空,传回“空”
user[info.split(' ',2)[1]]=dataSocket # 像user字典里添加新的键-值对
dataSocket.send("OK".encode()) # 传回ok
time.sleep(0.1)
for ll in user: # 遍历user,传回用户名
if (user[ll] == user[ll]): # 没卵用
for key in user.keys():
user[ll].send("R 空".encode())
# Note.write("R 空")
time.sleep(0.1)
else: # 与if一样的操作,只不过用户名不为空
user[info.split(' ',2)[1]]=dataSocket
dataSocket.send("OK".encode())
time.sleep(0.1)
for ll in user:
if (user[ll] == user[ll]):
for key in user.keys():
ppp = "R " + key
user[ll].send(ppp.encode())
# Note.write(ppp)
time.sleep(0.1)
#处理聊天业务
elif info.split(maxsplit=1)[0]=="C": # 如果请求是聊天
print(info.split(maxsplit=1)[1], end=" ") # 在服务端打印聊天信息
print(addr, end= " ") # 在服务端打印ip地址
print(time.strftime('%Y-%m-%d %H:%M:%S')) # 在服务端打印时间
for k in user: # 遍历user
if (user[k] != dataSocket): # 发送至所有人(除了自己)
fs = "C " + info.split(' ',1)[1] # 聊天内容
user[k].send(fs.encode()) # 发送聊天内容
# Note.write(fs)
#处理正常流程用户推出
elif info.split(' ',1)[0]=="Q": # 判断如果用户输入了exit的退出(好像不起作用)
del user[info.split(' ',1)[1]] # 删除这个用户
if user[info.split(' ',1)[1]] == " " or user[info.split(' ',1)[1]] == "": # 如果用户名为空
k.send(("空"+"已退出群聊").encode()) # 传回空退出了群聊
k.send("E " + "空".encode()) # 返回空
else:
k.send((info.split(' ',1)[1]+"已退出群聊").encode()) # 一样的操作,只不过用户名不为空
k.send(("E " + info.split(' ',1)[1]).encode())
break
# 发送的数据类型必须是bytes,所以要编码
# dataSocket.send(f'服务端接收到了信息 {info}'.encode())
#for p in range(len(a)):
#a.send(f'服务端接收到了信息 {info}'.encode())
except: # 处理意外情况,大多是因为客户端异常退出引起的
#print("123")
#print(user)
for key, k in list(user.items()): # 与消息长度为0一样的操作
#处理用户意外断开
if k == dataSocket:
#print(user[k])
del user[key]
#print(user)
if key == "" or key == " ":
for ka in user:
user[ka].send(("空" + "已退出群聊").encode())
user[ka].send(("E " + "空").encode())
break
else:
for ka in user:
user[ka].send((key + "已退出群聊").encode())
user[ka].send(("E " + key).encode())
break
#dataSocket.close()
dataSocket.close() # 循环结束后,没有必要再进行下去,所以关闭监听
# listenSocket.close()
# 类型:socket.AF_INET 可以理解为 IPV4
# 协议:socket.SOCK_STREAM
listenSocket = socket(AF_INET, SOCK_STREAM)
listenSocket.setsockopt(SOL_SOCKET, SOCK_STREAM, True)
listenSocket.ioctl(SIO_KEEPALIVE_VALS, (1, 60*1000, 30*1000))
# socket绑定地址和端口
listenSocket.bind(('0.0.0.0', 80))
listenSocket.listen()
# server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# server.bind(('0.0.0.0', 8000)) # (client客户端ip, 端口)
# server.listen() # 监听
print(f'服务端启动成功,在43.138.0.102端口等待客户端连接...')
# dataSocket, addr = listenSocket.accept()
# print('接受一个客户端连接:', addr)
while True:
dataSocket, addr = listenSocket.accept() # 获得一个客户端的连接(阻塞式,只有客户端连接后,下面才执行)
print('接受一个客户端连接:', addr)
if (1==1):
xd = threading.Thread(target=deal, args=(dataSocket, addr))
xd.start() # 启动一个线程
微软, 用户名