Python套接字错误:[Errno 9] 错误的文件描述符

5
我希望用Python制作一个服务器和客户端。它应该建立多个连接,一个是服务器向客户端发送信息的连接,另一个是客户端向服务器发送信息的连接。 第一个连接正常工作,但第二个连接出现了以下错误消息:
socket.error: [Errno 9] Bad file descriptor

这里是服务器:

import socket
import errno
import pickle

def Main():
    host = '188.174.233.99'
    port = 66666

    all_text = ['text1', 'text2', 'text3']

    all_description = ['Test \n Description1\n', 'Test \n Description1\n', 'Test \n Description1\n']

    all_images = ['unlock.png', 'unlock.png', 'unlock.png']
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
    s.bind((host, port))
    s.listen(1)


    while True:

        c, addr = s.accept()
        c.setblocking(0)

        print "Connection from: " + str(addr)


        command = c.recv(1024)

        if command == 'GIVEALL':
            textstring = pickle.dumps([all_text, all_images, all_description])#verwandelt Liste in String
            c.send(textstring)



        else:
            try:
                new_event = pickle.loads(command)
                print new_event
                caption = new_event[0]
                image = new_event[1]
                describtion = new_event[2]
                city = new_event[3]

            except:
                pass

        try:
            c.close()

            s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        except socket.error as e:
            if e.errno != errno.ECONNRESET:
                raise
            pass

if __name__ == '__main__':
    Main()

以下是客户端代码:

import socket import pickle

from kivy.properties import StringProperty
from kivy.properties import NumericProperty
from kivy.properties import ListProperty

class Netclient(object):

    def __init__(self):
        self.s = socket.socket()
        self.texte = []
        self.current = 'All'

        self.ip = '188.174.233.99'
        self.port = 66666

    def giveWid(self):
        print 'give Widgets executed'
        if self.current == 'All':
            self.texte, self.images, self.description = self.sentHOT(self.ip, self.port)

        return self.texte, self.images, self.description

    def sentHOT(self, host, port):

        self.s.connect((host, port))
        self.s.send('GIVEALL')#sends command

        recived_string = self.s.recv(1023)

        more_text = pickle.loads(recived_string)#verwandelt string in liste

        self.s.close()
        print 'closed'
        return more_text[0], more_text[1], more_text[2]


    def add_event(self, caption, image, description, city='Pawonkow'):
        new_event = [caption, image, description, city]
        new_compact_event = pickle.dumps(new_event)

        self.s.connect((self.ip, self.port))
        self.s.send(new_compact_event)

        self.s.close()


    n = Netclient()
    t, i, d = n.giveWid()
    print t
    n.add_event('new', 'new.png', 'ew event', 'Hanau')

服务器无法关闭连接!将每个连接放入线程中,在服务器端只接受“close”方法... - dsgdfg
如果想要拒绝客户端连接,您可以使用 close 方法。 - dsgdfg
可能是在Python套接字中出现Errno 9:坏文件描述符的重复问题。 - Evan Carroll
1个回答

5
原因是您正在尝试重新连接一个已经关闭的套接字。您必须要么创建一个新的套接字,要么重用旧的套接字,只要它还连接着。
在方法def sentHOT(...):中注释掉self.s.close()这一行,在方法def add_event(...)中注释掉self.s.connect((self.ip, self.port))这一行,然后应该可以工作了。此外,请参考这个教程,它可以帮助您进行套接字编程。

2
好的发现。我一开始没有理解问题。我以为他是指他同时启动了两个客户端。我已经删除了我的帖子,因为那不是正确的答案。 - jobou
如果为这两个函数都有一个新的套接字,它会是什么样子? - Gilgamesch von Uruk
@GilgameschvonUruk 你能再解释一下吗?你是指每次调用函数时都创建一个新的套接字吗? - mitghi
是的,我确实做到了,并且它也有点起作用,我应该发布代码吗? - Gilgamesch von Uruk
如果您愿意的话可以这样做。如果您能够查看各种网络架构(线程,本地多路复用API(epoll,select等)),那么这也会很有帮助。@jobou对此主题有很好的参考资料。 - mitghi
1
看这里:https://dev59.com/t2gv5IYBdhLWcg3wKthA#10810769,你有基本的本地Python类来完成这个任务。请注意末尾的带有Forking或Threading mixin的注释,因为原生的TCPServer表现为同步(它等待一个请求的结束才处理下一个)。 - jobou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接