【问题标题】:multiasting TypeError: argument must be an int, or have a fileno() methodmultiasting TypeError: 参数必须是 int,或者有 fileno() 方法
【发布时间】:2018-12-14 18:51:19
【问题描述】:

我有一个问题,我用 gui 创建了多播,我的程序需要 sys.stdin 但我的 gui 中有文本字符串。

sockets_list = [sys.stdin, server] 
read_sockets,write_socket, error_socket  = select.select(sockets_list,[],[])

此代码不起作用

def message(self, event):
    mess = self.write.get() 
    self.sockets_list = [mess, self.server]
    self.read_sockets, write_socket, error_socket  = select.select(self.sockets_list,[],[]) 
    print self.sockets_list
    self.write.delete(0, Tkinter.END)
    if mess != '':
      self.mess1.configure(state = NORMAL)
      self.all_users.append('Adam')
      for socks in self.read_sockets:
        if socks == self.server:
            message = socks.recv(2048)
            self.mess1.insert(Tkinter.END, '%s> %s \n' %(self.nick, message)) #wyswietla wprowadzony tekst
            self.mess1.see(Tkinter.END) 
        else:
            message = mess
            self.server.send(message)
            print self.nick
            print message
      self.mess1.see(Tkinter.END) 
      self.mess1.configure(state = DISABLED)

我想在多播的基础上创建一个信使我从一个客户端发送一条消息 - 我去服务器并将它发送给其余的客户端。问题是我无法使用在 gui 中输入的消息,它在终端中工作

所有代码

web_pr_less2_client.py - 客户端

dup.py - 服务

https://github.com/Antoni-Hp/Web_programing/tree/master/Python_web_programing_less2

【问题讨论】:

    标签: python-2.7 sockets multicastsocket


    【解决方案1】:

    问题作者所说的问题是“代码不起作用”。虽然作者试图为导致特定异常抛出的特定错误找到解决方案,但单独修复它并不能解决代码无法正常工作的问题。似乎作者才刚刚开始学习如何编写 GUI 应用程序。

    我对 Tkinter 知之甚少,但无论如何我都会通过解释我在这里看到的问题来提供帮助。

    1. 问题中提出的message 方法被调用以响应“提交消息”事件。但是,此方法还尝试读取可能在任何给定时间从服务器到达的消息。这意味着用户在他们自己发送消息之前不会看到来自服务器的任何新消息。这段“从服务器读取”的代码应该从这个方法中移出并单独处理。

      现在,正如我之前所说,我不熟悉 Tkinter,所以我不能声称我知道这里最好的方法是什么,但通常情况下,使用 GUI 应用程序监听后台事件需要通过等待通过回调函数或通过轮询我们在后台等待的事件来到达“就绪”事件。这是如何实现的取决于所使用的技术(定时器、线程、带有回调的 OS API 函数)。

      在你的情况下:

      1.1。将读取操作提取到单独的方法中。
      1.2.使用 Tkinter 计时器定期调用此方法。
      1.3.套接字上的select() 超时时间很短(尝试0.01
      1.4.如果套接字已准备好读取,请读取它并将其附加到聊天窗口。

      这是一个原始的解决方案,因为 0.01 超时会停止您的应用程序,并且在生产级软件中不应在主线程中完成,但这是一个很好的起点。

    2. 消息提交时抛出异常是由于尝试使用从文本输入小部件获得的mess 变量,就好像它是一个I/O 句柄一样,而实际上它是一个str。 I/O 句柄是文件、文件描述符、套接字、管道。 str 是一种数据类型,不能传递给 select()。但是,您可以通过套接字发送它而无需多加注意,即。

      def message(self, event):
          message = self.write.get()
          self.write.delete(0, Tkinter.END)
          self.server.send(message)
          self.mess1.configure(state=NORMAL)
          self.mess1.insert(Tkinter.END, '%s> %s \n' %(self.nick, message))
          self.mess1.see(Tkinter.END)
          self.mess1.configure(state=DISABLED)
      

    此外,除了手头的问题,我的一般建议是:

    您的代码未遵循 PEP8 样式建议。虽然这不会影响您的软件功能,但您可以重新考虑遵循这些规则。它们是 Python 语言的作者正式推荐的,很可能你在网上找到的大多数 Python 代码都会跟随它们。对您的代码运行 flake8 检查显示 351 次违规。

    我还建议专注于对符号进行更精确的命名。

    • def message 应该是def on_message_send_requested(我使用了on 前缀,因为由于event 参数的存在,此方法只能用作回调),
    • self.server 应该是self.connection_socket
    • mess 应该是message
    • self.write 应该是 self.text_input

    【讨论】:

      【解决方案2】:

      我使用了after() 函数,它可以工作。

      @ZalewaPL 谢谢你的帮助 :)

      解决方案:

       def read_from_server(self):
          read_sockets, write_socket, error_socket = 
          select.select([self.connection_socket],[],[], 0.1)
          for socks in read_sockets:
            if socks == self.connection_socket:
              message = socks.recv(2048)
              message = message.split(";;")
              self.mess1.configure(state = NORMAL)
              self.mess1.insert(Tkinter.END, '%s> %s \n' %(message[0], message[1]))
              self.mess1.see(Tkinter.END)
              self.mess1.configure(state = DISABLED)
          self.main.after(1, self.read_from_server)
      
      
        def on_message_send_requested(self, event):
          message = self.text_input.get() # pobiera tekst z okienka write
          self.text_input.delete(0, Tkinter.END)
          if message != '':
            self.mess1.configure(state = NORMAL)
            send_message = "%s;;%s" %(self.nick, message)
            self.connection_socket.send(send_message)
            self.mess1.insert(Tkinter.END, '%s> %s \n' %(self.nick, message)) 
            self.mess1.see(Tkinter.END) #pokazuje zawsze najnowszy wpis
            self.mess1.configure(state = DISABLED)
      

      【讨论】:

        猜你喜欢
        • 2016-02-20
        • 1970-01-01
        • 2021-02-15
        • 2017-05-13
        • 2014-02-26
        • 1970-01-01
        • 2017-03-03
        • 1970-01-01
        • 2020-05-05
        相关资源
        最近更新 更多