首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >'socket.error:[Errno 9]坏文件描述符‘当我运行我的客户端

'socket.error:[Errno 9]坏文件描述符‘当我运行我的客户端
EN

Stack Overflow用户
提问于 2015-12-12 10:20:54
回答 1查看 5.3K关注 0票数 1

当我运行我的客户时,我的服务器崩溃了,

上面写着:

代码语言:javascript
复制
Traceback (most recent call last):
      File "C:/Users/Or/PycharmProjects/2.6/cyber.py", line 17, in <module>
        data = client_socket.recv(1024)
      File "C:\Python27\lib\socket.py", line 174, in _dummy
        raise error(EBADF, 'Bad file descriptor')
    socket.error: [Errno 9] Bad file descriptor

服务器:

代码语言:javascript
复制
import socket
import random
import time

server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 8820))
server_socket.listen(1)

(client_socket, client_address) = server_socket.accept()

TIME = time.asctime(time.localtime())
NAME = "Frank"
RAND = random.randrange(1,10)
EXIT = client_socket.close()
options = [TIME, NAME, RAND, EXIT]

data = client_socket.recv(1024)
if data == str(TIME):
    client_socket.send('Time is: ' + TIME)
elif data == str(NAME):
    client_socket.send('My name is: ' + NAME)
elif data == str(RAND):
    client_socket.send(RAND)
elif data == str(EXIT):
    EXIT




client_socket.close()
server_socket.close()

客户:

代码语言:javascript
复制
import socket

my_socket = socket.socket()
my_socket.connect(('127.0.0.1', 8820))

theData = raw_input("enter command")
options = ['TIME', 'NAME', 'RAND', 'EXIT']
for z in options:
    if theData == z:
        my_socket.send(theData)
        data = my_socket.recv(1024)
        print data
    else:
        theData = raw_input("enter a real command")

我该怎么办?

EN

回答 1

Stack Overflow用户

发布于 2015-12-12 12:03:03

在客户端连接之前,服务器blocks中的以下行:

代码语言:javascript
复制
(client_socket, client_address) = server_socket.accept()

在客户端连接之后,您的服务器执行以下操作:

代码语言:javascript
复制
  .... = client_socket.close()

然后您的服务器执行以下操作:

代码语言:javascript
复制
 client_socket.recv(1024)

那是行不通的。

我该怎么办?

删除这一行:

代码语言:javascript
复制
EXIT = client_socket.close()

您的代码还有其他几个问题:

1)您不知道send()将实际发送多少数据:

socket.send(字节、标志) ..。 应用程序负责检查所有数据是否已发送;如果仅传输了一些数据,则应用程序需要尝试传递其余数据。https://docs.python.org/3/library/socket.html#socket.socket.send

换句话说,send()不一定能够一次发送整个消息--因此send()返回实际发送的字节数。您可以使用sendall()来改善这个问题。

2)然而,对于send()sendall(),您不知道您的数据是以10块、5块还是全部以1块的方式发送的,因此您必须使用一个循环才能对整个消息进行recv()

代码语言:javascript
复制
data = []

while True:
    chunk = my_socket.recv()
    if not chunk: break  #When the other side closes the socket, chunk = ''
    data.append(chunk)

all_data = ''.join(data)

当另一侧关闭套接字时,recv()将返回一个空字符串。

3)现在的大问题是:

代码语言:javascript
复制
data = client_socket.recv(1024)

您的服务器必须在循环中使用recv()来确保从客户端读取整个消息:

代码语言:javascript
复制
data = []

while True:
    chunk = client_socket.recv()
    if not chunk: break  #When the other side closes the socket, chunk = ''
    data.append(chunk)

all_data = ''.join(data)

但是,read循环如何知道它何时读取了所有数据?注意,正如所写的那样,当另一侧关闭套接字时,循环终止,导致recv()返回一个空字符串,该字符串终止while循环。但是,在您的示例中,客户端在send()之后不会关闭套接字,因此服务器的recv()永远不会返回空字符串,而while循环将继续尝试recv()--但是客户机将完成发送消息并等待响应。死锁。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34238713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档