错误的文件描述符socket.recv错误&解决方案,但我不知道为什么

时间:2014-12-08 08:39:51

标签: python sockets

以下是服务代码:

from socket import *
from time import ctime

HOST = ''
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

try:
    while True:
        print 'Wait for connection...'
        tcpCliSock, addr = tcpSerSock.accept()
        print '...connnet from:', addr

        while True:
            data = tcpCliSock.recv(BUFSIZ)
            if not data:
                break
            tcpCliSock.send('[%s] %s' % (ctime(), data))
            tcpCliSock.close()
except (EOFError, KeyboardInterrupt):
    tcpSerSock.close()

以下是客户端代码:

from socket import *

HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)

while True:
    data = raw_input(">")
    if not data:
        break
    tcpCliSock.send(data)

    data = tcpCliSock.recv(BUFSIZ)
    if not data:
        break
    print data
    break

tcpCliSock.close()

当我运行服务代码时,它会显示:

Traceback (most recent call last):
  File "G:/python/tcpServ&tcpClnt/tsTserv.py", line 22, in <module>
    data = tcpCliSock.recv(BUFSIZ)
  File "C:\Python27\lib\socket.py", line 170, in _dummy
    raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor

但客户仍然可以获取信息。然后我在socket.py中更改了代码,它运行了!但我不知道为什么。

PS。我改变了:

class _closedsocket(object):
    __slots__ = []
    def _dummy(*args):
        raise error(EBADF, 'Bad file descriptor')

到此:

class _closedsocket(object):
    __slots__ = []
    def _dummy(*args):
        pass

1 个答案:

答案 0 :(得分:0)

发生错误是因为您调用了前面关闭的套接字的recv()。执行顺序:

        …
            data = tcpCliSock.recv(BUFSIZ)  # data from tcpCliSock.send(data) is received
# not true: if not data:
# skipped:      break
            tcpCliSock.send('[%s] %s' % (ctime(), data))    # reply data is sent to client
            tcpCliSock.close()                              # the socket is closed!
        while True:                                         # the loop is reiterated
            data = tcpCliSock.recv(BUFSIZ)                  # the closed socket is used!

也许你只是错误地缩进了tcpCliSock.close()。如果你坚持下去,那么一切都有效:

        while True:
            data = tcpCliSock.recv(BUFSIZ)
            if not data:
                break
            tcpCliSock.send('[%s] %s' % (ctime(), data))
        tcpCliSock.close()
  

然后我更改了socket.py中的代码,它运行了!但我不知道为什么。

raise …更改为pass,您只需将错误扫到地毯下即可。