multiasting TypeError:参数必须为int或具有fileno()方法

时间:2018-12-14 18:51:19

标签: python-2.7 sockets multicastsocket

我有问题,我已使用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)

我想在多播的基础上创建一个Messenger,我从一个客户端发送一条消息-我转到服务器,然后将其发送给其余的客户端。问题是我无法使用在gui中输入的消息,并且该消息在终端中有效

所有代码

web_pr_less2_client.py-客户端

dup.py-服务

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

2 个答案:

答案 0 :(得分: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句柄,而实际上是{{1 }}。 I / O句柄是文件,文件描述符,套接字,管道。 str是一种数据类型,不能传递给str。但是,您可以直接通过套接字发送它,即无需担心。

    select()

除了眼前的问题,我的一般建议是:

您的代码未遵循PEP8样式建议。尽管这在功能上不会影响您的软件,但是您可以重新考虑遵循这些规则。 Python语言的作者正式推荐使用它们,并且很可能您在网上找到的大多数Python代码都将遵循它们。对代码运行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) 检查会发现351次违规。

我还建议重点关注符号的更精确命名。

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

答案 1 :(得分:0)

我使用了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)