Python套接字和线程已赢得';我没有收到消息

Python套接字和线程已赢得';我没有收到消息,python,Python,我正在尝试创建聊天服务,但我的GUI不会收到我发送的消息。我可以连接到服务器,但当我发送消息时,我不会广播消息。我们也在尝试创建多个聊天室,但我不知道如何使用套接字实现这一点 当我连接到服务器时,它会询问我的姓名并广播我已加入聊天,但是我发送的任何非{quit}的消息都不会被广播。我不确定是发送部分还是接收部分导致了问题。任何提示都将不胜感激 from socket import AF_INET, socket, SOCK_STREAM from threading import Thread

我正在尝试创建聊天服务,但我的GUI不会收到我发送的消息。我可以连接到服务器,但当我发送消息时,我不会广播消息。我们也在尝试创建多个聊天室,但我不知道如何使用套接字实现这一点

当我连接到服务器时,它会询问我的姓名并广播我已加入聊天,但是我发送的任何非{quit}的消息都不会被广播。我不确定是发送部分还是接收部分导致了问题。任何提示都将不胜感激

from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread


def accept_incoming_connections():
"""Sets up handling for incoming clients."""
    while True:
        client, client_address = SERVER.accept()
        print("%s:%s has connected." % client_address)
        client.send(bytes("Greetings from SlackChat! Now type your name and press enter!", "utf8"))
        addresses[client] = client_address
        Thread(target=handle_client, args=(client,)).start()


def handle_client(client):  # Takes client socket as argument.
"""Handles a single client connection.""" 

name = client.recv(BUFSIZ).decode("utf8")
welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % name
client.send(bytes(welcome, "utf8"))
msg = "%s has joined the chat!" % name
broadcast(bytes(msg, "utf8"))
clients[client] = name

while True:
    msg = client.recv(BUFSIZ)
    if msg != bytes("{quit}", "utf8"):
        broadcast(msg, name+": ")
    else:
        client.send(bytes("{quit}", "utf8"))
        client.close()
        del clients[client]
        broadcast(bytes("%s has left the chat." % name, "utf8"))
        break


def broadcast(msg, prefix=""):  # prefix is for name identification.
"""Broadcasts a message to all the clients."""

for sock in clients:
    sock.send(bytes(prefix, "utf8")+msg)


clients = {}
addresses = {}

HOST = ''
PORT = 33000
BUFSIZ = 1024
ADDR = (HOST, PORT)

SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.bind(ADDR)

if __name__ == "__main__":
    SERVER.listen(5)
    print("Waiting for connection...")
    ACCEPT_THREAD = Thread(target=accept_incoming_connections)
    ACCEPT_THREAD.start()
    ACCEPT_THREAD.join()
    SERVER.close()
GUI代码:

import tkinter
from tkinter import messagebox
from socket import AF_INET, socket, SOCK_STREAM
from threading import Thread


def receive():
"""Handles receiving of messages."""
    while True:
        try:
            msg = client_socket.recv(BUFSIZ).decode("utf8")
            list2.insert(tkinter.END, msg)
        except OSError:  # Possibly client has left the chat.
            break
def send(event=None):  # event is passed by binders.
"""Handles sending of messages."""
    msg = message_text.get()
    message_text.set("")  # Clears input field.
    client_socket.send(bytes(msg, "utf8"))
    if msg == "{quit}":
        client_socket.close()
        window.quit()
def on_closing(event=None):
"""This function is to be called when the window is closed."""
    message_text.set("{quit}")
    send()
def Create_command():
    pass
def clear_command():
    message_text.set("")



window=tkinter.Tk() # TK method that creates a windows objective
window.wm_title("Zlack Chat")

l1=tkinter.Label(window, text="Chat Rooms")                  # chat room label
l1.grid(row=0,column=0, columnspan = 2, pady = 10)

l2=tkinter.Label(window, text="Chat")                                  # chat list label
l2.grid(row=0,column=3, columnspan = 2)

l3=tkinter.Label(window, text="Create Chat Room")                  # create chat room label
l3.grid(row=3,column=0, pady = (10,0))

l4=tkinter.Label(window, text="Message")                               
# message label
l4.grid(row=3,column=3, sticky = tkinter.W, padx= 10, pady = (10,0))

# Display Titles# Display text entry fields          
textvariable=Chat_rooms_text,
Chat_rooms_text=tkinter.StringVar()
list1=tkinter.Listbox(window, width=45, height = 20)                                           
# chat room list box
list1.grid(row=1,column=0, columnspan = 2, padx = (10,0))

create_text=tkinter.StringVar()
e3=tkinter.Entry(window,textvariable=create_text, width=25)             # create chat name entry
e3.grid(row=3 , column=1, pady = (10,0), sticky = tkinter.E)

message_text=tkinter.StringVar()
message_text.set("Enter your message here.")
e4=tkinter.Entry(window,textvariable=message_text, width = 70)          # message entry 
e4.grid(row=3, column=3, columnspan = 2, sticky = tkinter.E, pady = (10,0))
e4.bind("<Return>", send)

# display listbox and attached a Scrollbar
list2=tkinter.Listbox(window, width = 80, height = 20)                                           
# message feed/history
list2.grid(row=1, column=3, columnspan = 2, padx = (10,0)) # we want to span across multiple rows and columns

sb1 = tkinter.Scrollbar(window)                                         # chat list scroll bar
sb1.grid(row=1, column=2, rowspan=2,     
sticky=tkinter.N+tkinter.S+tkinter.W)

list1.configure(yscrollcommand=sb1.set)
sb1.configure(command=list1.yview)

sb2 = tkinter.Scrollbar(window)
sb2.grid(row=1, column=5, rowspan=2, stick=tkinter.N+tkinter.S+tkinter.W, padx=(0,10))

list2.configure(yscrollcommand=sb2.set)
sb2.configure(command=list2.yview)

# Display Buttons
b1=tkinter.Button(window, text="Create", width=15, command=Create_command)      # create button
b1.grid(row=4, column=0, columnspan = 2, sticky = tkinter.E, pady = 10)
b2=tkinter.Button(window, text="Clear", width=15, command=clear_command)        # clear button
b2.grid(row=4, column=3, pady = 10, padx = (250, 0))
b3=tkinter.Button(window, text="Enter", width= 15, command=send)       # enter button
b3.grid(row=4, column=4, sticky = tkinter.E, pady = 10)

HOST = input('Enter host: ')
PORT = input('Enter port: ')
if not PORT:
    PORT = 33000
else:
    PORT = int(PORT)

BUFSIZ = 1024
ADDR = (HOST, PORT)

client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(ADDR)

receive_thread = Thread(target=receive)
receive_thread.start()

window.mainloop()
导入tkinter
从tkinter导入消息框
从socket导入AF_INET、socket、SOCK_流
从线程导入线程
def receive():
“”“处理邮件的接收。”“”
尽管如此:
尝试:
msg=client_socket.recv(BUFSIZ).decode(“utf8”)
列表2.插入(tkinter.END,msg)
除了OSError:#可能客户端已离开聊天室。
打破
def send(event=None):#事件由绑定器传递。
“”“处理消息的发送。”“”
msg=message\u text.get()
message_text.set(“”)清除输入字段。
客户端\u socket.send(字节(msg,“utf8”))
如果msg==“{quit}”:
client_socket.close()
window.quit()
def on_关闭(事件=无):
“”“当窗口关闭时调用此函数。”“”
message_text.set(“{quit}”)
发送()
def Create_命令():
通过
def clear_命令():
消息文本集(“”)
window=tkinter.Tk()#创建windows目标的Tk方法
window.wm_标题(“Zlack聊天”)
l1=tkinter.Label(窗口,text=“聊天室”)#聊天室标签
l1.网格(行=0,列=0,列span=2,pady=10)
l2=tkinter.Label(窗口,text=“Chat”)#聊天列表标签
l2.网格(行=0,列=3,列span=2)
l3=tkinter.Label(窗口,text=“创建聊天室”)#创建聊天室标签
l3.网格(行=3,列=0,pady=(10,0))
l4=tkinter.Label(窗口,text=“消息”)
#消息标签
l4.网格(行=3,列=3,粘性=tkinter.W,padx=10,pady=(10,0))
#显示标题#显示文本输入字段
text变量=聊天室\文本,
聊天室text=tkinter.StringVar()
list1=tkinter.Listbox(窗口,宽度=45,高度=20)
#聊天室列表框
列表1.grid(行=1,列=0,列span=2,padx=(10,0))
create_text=tkinter.StringVar()
e3=tkinter.Entry(窗口,textvariable=create_text,width=25)#创建聊天名称条目
e3.网格(行=3,列=1,pady=(10,0),粘性=tkinter.E)
message_text=tkinter.StringVar()
message_text.set(“在此处输入您的消息”)
e4=tkinter.Entry(窗口,文本变量=message_text,宽度=70)#消息条目
e4.网格(行=3,列=3,列span=2,粘性=tkinter.E,pady=(10,0))
绑定(“,发送)
#显示列表框并附加一个滚动条
list2=tkinter.Listbox(窗口,宽度=80,高度=20)
#消息源/历史记录
list2.grid(row=1,column=3,columnspan=2,padx=(10,0))#我们希望跨越多个行和列
sb1=tkinter.Scrollbar(窗口)#聊天列表滚动条
sb1.网格(行=1,列=2,行跨度=2,
粘性=tkinter.N+tkinter.S+tkinter.W)
list1.configure(yscrollcommand=sb1.set)
sb1.configure(命令=list1.yview)
sb2=tkinter.Scrollbar(窗口)
sb2.grid(行=1,列=5,行跨度=2,棒=tkinter.N+tkinter.S+tkinter.W,padx=(0,10))
list2.configure(yscrollcommand=sb2.set)
sb2.configure(命令=list2.yview)
#显示按钮
b1=tkinter.Button(窗口,text=“创建”,宽度=15,命令=Create_命令)#创建按钮
b1.网格(行=4,列=0,列span=2,粘性=tkinter.E,pady=10)
b2=tkinter.Button(窗口,text=“Clear”,宽度=15,命令=Clear_命令)#清除按钮
b2.网格(行=4,列=3,pady=10,padx=(250,0))
b3=tkinter.按钮(窗口,text=“回车”,宽度=15,命令=send)#回车按钮
b3.网格(行=4,列=4,粘性=tkinter.E,pady=10)
主机=输入('输入主机:')
端口=输入('输入端口:')
如果不是端口:
端口=33000
其他:
端口=int(端口)
BUFSIZ=1024
地址=(主机,端口)
客户端\u套接字=套接字(AF\u INET,SOCK\u STREAM)
客户端\u套接字连接(地址)
接收线程=线程(目标=接收)
receive_thread.start()
window.mainloop()

您的服务器似乎没有保留对它创建的
线程的引用。您在
def handle\u客户端中出现缩进错误(…
您的代码假定它将收到一条完整的消息,如“{quit}”这可能会发生,但通常不会发生,因为TCP是一种流协议,它不能保证在一个
send()
中发送的内容将在一个
recv()中接收
-因此,您需要更智能地处理接收,确保在有值得处理的内容之前不会处理接收到的数据,然后不会丢弃从下一条消息接收到的数据。这需要能够界定消息,这就是基于TCP的RFC协议具有消息终止符的原因。