首页 > 解决方案 > python为什么我不断从select.select中得到ValueError:文件描述符不能是负整数(-1)

问题描述

我尝试使用套接字和选择制作一个简单的 tkinter GUI 聊天界面,但是file descriptor cannot be a negative integer (-1)在连接到服务器时不断收到 ValueError。表明:

    r,w,e = select.select(socket_list,[],[],0)
    ValueError: file descriptor cannot be a negative integer (-1)

以下是客户端的完整脚本:

    from tkinter import *
    import socket,select,sys,time
    HOST = ''
    PORT = 0

    class Connection():
        def __init__(self):

            self.t1 = Toplevel()
            self.scrollbar = Scrollbar(self.t1)
            self.textbox = Text(self.t1,yscrollcommand=self.scrollbar.set)
            self.e3 = Entry(self.t1)
            self.b2 = Button(self.t1,text='close window',command=self.close_window)

            self.s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            self.s.settimeout(2)

            self.scrollbar.pack(side=LEFT,fill=Y)
            self.textbox.pack()
            self.e3.pack(fill=X)
            self.b2.pack(side=BOTTOM,fill=X)

            self.connect_server()
            self.in_and_out()
        def connect_server(self):
            global HOST, PORT
            try:
                self.s.connect((str(HOST),int(PORT)))
            except Exception as e:
                print('Error with [%s,%s] Exception type: %s'% (HOST,PORT,e))
                self.close_window()
        def in_and_out(self):
            while True:
                root.update_idletasks()
                root.update()
                socket_list = [sys.stdin,self.s]
                r,w,e = select.select(socket_list,[],[],0)
                for sock in r:
                    if sock==self.s:
                        data=self.s.recv(4096).decode()
                        if not data:
                            print('disconnected from server.')
                            self.close_window()
                        else:
                            print(data)
                            self.textbox.insert(END,'>: %s\n'% data)
                    else:
                        name = self.s.getsockname()
                        self.e3.bind("<Return>",self.enter_pressed)
        def enter_pressed(self):
                msg = self.e3.get()
                self.textbox.insert(END,">: %s\n"% msg)
                self.s.send(msg.encode())
                self.e3.delete(0,'end')
        def close_window(self):
                self.s.close()
                self.t1.destroy()

    def try_linking():
        global HOST, PORT
        HOST = s1.get()
        PORT = i1.get()
        print(HOST,PORT)
        conn = Connection()

    root = Tk()

    l1 = Label(root,text='Host:')
    l2 = Label(root,text='Port:')
    s1 = StringVar()
    i1 = IntVar()
    e1 = Entry(root,textvariable=s1)
    e2 = Entry(root,textvariable=i1)
    s1.set('192.168.4.101')
    i1.set(9009)
    b1 = Button(root,text='Connect',command=try_linking)

    l1.pack()
    e1.pack()
    l2.pack()
    e2.pack()
    b1.pack(fill=X)

    if __name__=='__main__':
        root.mainloop()

这个脚本应该通过输入主机和端口开始,然后按下try_link按钮,然后在连接时弹出一个聊天窗口。请指教,谢谢

标签: pythonselecttkinter

解决方案


推荐阅读