我正在尝试提供聊天服务,但是我的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()