Python 客户端/服务器问题
我正在用Python做一个小项目。这个项目有一个客户端和一个服务器。服务器会监听连接,一旦收到连接,就会等待客户端的输入。这个项目的想法是,客户端可以连接到服务器并执行一些系统命令,比如ls和cat。以下是我的服务器代码:
import sys, os, socket
host = ''
port = 50105
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("Server started on port: ", port)
s.listen(5)
print("Server listening\n")
conn, addr = s.accept()
print 'New connection from ', addr
while (1):
rc = conn.recv(5)
pipe = os.popen(rc)
rl = pipe.readlines()
file = conn.makefile('w', 0)
file.writelines(rl[:-1])
file.close()
conn.close()
这是我的客户端代码:
import sys, socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = input('Port: ')
s.connect((host, port))
cmd = raw_input('$ ')
s.send(cmd)
file = s.makefile('r', 0)
sys.stdout.writelines(file.readlines())
当我启动服务器时,输出是正确的,显示服务器正在监听。但是当我用客户端连接并输入一个命令时,服务器就出现了错误并退出,错误信息如下:
Traceback (most recent call last):
File "server.py", line 21, in <module>
rc = conn.recv(2)
File "/usr/lib/python2.6/socket.py", line 165, in _dummy
raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor
在客户端那边,我能看到ls的输出,但服务器却出现了问题。
2 个回答
3
如果你想让你的客户端重复执行某个操作,只需要在里面加一个循环就行了;)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = input('Port: ')
s.connect((host, port))
while True:
cmd = raw_input('$ ')
s.send(cmd)
file = s.makefile('r', 0)
sys.stdout.writelines(file.readlines())
这样应该更接近你想要的效果。
其他评论:
s.listen(1)
这个语句最好放在while循环外面。你只需要调用一次listen
。
pipe = os.popen(rc)
os.popen已经不推荐使用了,建议用subprocess模块来代替。
file = s.makefile('r', 0)
你打开了一个文件,但从来没有关闭它。你应该在sys.stdout.writelines()
调用之后加上file.close()
。
编辑:为了回答下面的评论;由于长度和格式原因在这里处理。
目前的情况是,你只从套接字读取了一次,然后立刻关闭了它。因此,当客户端尝试发送下一个命令时,它会发现服务器关闭了套接字,从而出现错误。
解决办法是修改你的服务器代码,使其能够处理多个命令。注意,这个问题可以通过引入另一个循环来解决。
你需要把
rc = conn.recv(2)
pipe = os.popen(rc)
rl = pipe.readlines()
fl = conn.makefile('w', 0)
fl.writelines(rl[:-1])
放在另一个while True:
循环里面,这样它就会一直重复,直到客户端断开连接,然后再把这个循环放在一个try-except块里,以捕获当客户端断开连接时conn.recv()抛出的IOError。
这个try-except块应该看起来像这样:
try:
# the described above loop goes here
except IOError:
conn.close()
# execution continues on...
6
你的代码先调用了 conn.close()
,然后又回到 conn.recv()
这一步,但这时候 conn
已经关闭了。