Python套接字(Socket Error Bad File Descriptor)

16
以下的receiveFile()函数从套接字读取文件名和文件数据,并使用定界符$进行拆分。
但是我无法关闭套接字,会出现坏的文件描述符错误。如果我将self.server_socket.close()语句注释掉,则不会出现错误,但套接字会一直保持监听状态。
代码:
def listen(self):
    self.server_socket.listen(10)
    while True:
        client_socket, address = self.server_socket.accept()
        print 'connected to', address
        self.receiveFile(client_socket)



def receiveFile(self,sock):
    data = sock.recv(1024)
    data = data.split("$");
    print 'filename', data[0]
    f = open(data[0], "wb")
    #data = sock.recv(1024)
    print 'the data is', data[1]
    f.write(data[1])
    data = sock.recv(1024)
    while (data):
        f.write(data)
        data=sock.recv(1024)
    f.close()
    self.server_socket.close()
    print 'the data is', data
    print "File Downloaded"

Traceback:

Traceback (most recent call last):
  File "server.py", line 45, in <module>
    a = Server(1111)
  File "server.py", line 15, in __init__
    self.listen()
  File "server.py", line 20, in listen
    client_socket, address = self.server_socket.accept()
  File "c:\Python27\lib\socket.py", line 202, in accept
    sock, addr = self._sock.accept()
  File "c:\Python27\lib\socket.py", line 170, in _dummy
    raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor

1
错误可能不是来自那段代码,而是你调用self.server_socket.accept()的地方 - 如果能够包含更多代码和完整的回溯信息会有所帮助。 - Aya
所以,你的想法是希望服务器在接收到文件后关闭,还是只想关闭活动连接? - Aya
@aya 在这段代码中,我正在尝试在接收到文件后关闭服务器。 - Ali Ahmad
2个回答

13

你正在关闭服务器监听的套接字,并在此之后再次调用 accept()。

要完成接收一个文件,应该关闭客户端连接的套接字(在函数 receiveFile 中的 sock)。


我理解你的意思,正确关闭套接字和关闭服务器的顺序是什么? - Ali Ahmad
2
这取决于您何时需要关闭服务器。如果您只想接收一个文件,请关闭客户端连接,然后关闭监听套接字。 - Nickolay Olshevsky

5

在这段代码中,我正在尝试在文件接收后关闭服务器。

你需要的是一些方法,可以在想关闭服务器时跳出while True循环。一个简单的解决方案是利用关闭服务器套接字时生成的异常...

def listen(self):
    self.server_socket.listen(10)
    while True:
        try:
            client_socket, address = self.server_socket.accept()
        except socket.error:
            break
        print 'connected to', address
        self.receiveFile(client_socket)
    print 'shutting down'

谢谢 @aya,我通过将 receiveFile 函数的值返回来绕过循环。 - Ali Ahmad

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