我们正试图让我们的python信使系统更有效率。目前,客户端和服务器在运行和通信时都使用了大量的CPU。我们怀疑这是由于接收/连接循环不断尝试接收消息或用户/密码。 消息接收循环如下:
def recvmsg():
global decrypted_text
while not shutdown:
response = s.recv(4096).decode('utf-8')
response = decrypt(response)
if response.startswith("dict_keys(['"):
formatted = response.replace("dict_keys(['", "")
formatted = formatted.replace("'])", "")
formatted = formatted.replace("'", "")
output_field.configure(state = "normal")
output_field.insert(END, "Connected users: " + formatted + "\n")
output_field.see(END)
output_field.configure(state = "disabled")
else:
output_field.configure(state = "normal")
output_field.insert(END, response + "\n")
output_field.see(END)
output_field.configure(state = "disabled")
我们正在尝试利用select模块让循环等待传入流量而不是循环并且无法进入无穷大。 我们在这里看了一下:http://ilab.cs.byu.edu/python/select/echoserver.html但是我们没有达到很远,因为我们收到了这个错误: [WinError 10022]提供了无效的参数。我们还在这里查看了python文档:https://docs.python.org/3/library/select.html?highlight=select#module-select
答案 0 :(得分:0)
您可能会发现this answer有助于实施您的服务器。如果您希望更完整的服务器实现,也可以提供。在开发复杂版本的服务器时,开发了各种功能,包括朋友列表,私人消息和个人通信渠道。
<强> Simple_Server.py 强>
#! /usr/bin/env python3
import socket, select
def main():
a = [socket.socket(socket.AF_INET, socket.SOCK_STREAM)] # socket array
a[0].bind(('', 8989))
a[0].listen(5)
while True:
for b in select.select(a, [], [])[0]: # ready socket
if b is a[0]:
a.append(b.accept()[0])
else:
try:
c = b.recv(1 << 12) # sent message
except socket.error:
b.shutdown(socket.SHUT_RDWR)
b.close()
a.remove(b)
else:
for d in (d for d in a[1:] if d is not b): # message sink
d.sendall(c)
if __name__ == '__main__':
main()
<强> MultichatClient.py 强>
#! /usr/bin/env python3
from safetkinter import *
from tkinter.constants import *
import socket
import sys
class MultichatClient(Frame):
after_handle = None
def __init__(self, master, remote_host):
super().__init__(master)
self.message_area = ScrolledText(self, width=81, height=21,
wrap=WORD, state=DISABLED)
self.message_area.grid(sticky=NSEW, columnspan=2)
self.send_area = Entry(self)
self.send_area.bind('<Return>', self.keyPressed)
self.send_area.grid(sticky=EW)
b = Button(self, text='Send', command=self.mouseClicked)
b.grid(row=1, column=1)
self.send_area.focus_set()
try:
self.remote = socket.create_connection((remote_host, 8989))
except socket.gaierror:
print('Could not find host {}.'.format(remote_host))
except socket.error:
print('Could not connect to host {}.'.format(remote_host))
else:
self.remote.setblocking(False)
self.after_handle = self.after_idle(self.dataready)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
@classmethod
def main(cls, args):
root = Tk()
root.title('MultichatClient version 1.0')
m = cls(root, args[0])
m.grid(sticky=NSEW)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
return 1
def dataready(self):
try:
s = self.remote.recv(1 << 12).decode()
except socket.error:
pass
else:
self.message_area['state'] = NORMAL
self.message_area.insert(END, s)
self.message_area['state'] = DISABLED
self.message_area.see(END)
self.after_handle = self.after(100, self.dataready)
def destroy(self):
if self.after_handle:
self.after_cancel(self.after_handle)
super().destroy()
def mouseClicked(self, e=None):
self.remote.sendall(self.send_area.get().encode() + b'\r\n')
self.send_area.delete(0, END)
keyPressed = mouseClicked
if __name__ == '__main__':
sys.exit(MultichatClient.main(sys.argv[1:]))