我正在尝试通过现有客户端上的套接字库远程更改 cwd,但每次发送实际命令cd .."时我都会遇到麻烦.
I am trying to remotely change the cwd via socket lib on existing client, but I am running into the trouble every time I send the actual command "cd ..".
服务器:
import socket, subprocess, os, sys s = socket.socket() host = socket.gethostname() ip = socket.gethostbyname(host) port = 8080 s.bind((ip,port)) s.listen(5) c, a = s.accept() fr = c.recv(10000) cwd = fr print("IP: "+str(a[0])+":"+str(a[1])+"\tCONNECTED") while True: cmd = raw_input("\n"+cwd+"> ") if cmd != "": c.sendall(cmd) data = c.recv(1024) print("\n"+data) if cmd == "cd ..": c.sendall(cmd) cwd = c.recv(1024)客户:
import socket, subprocess, os, sys i = 1 cwd = os.getcwd() while 1: s = socket.socket() host = socket.gethostname() ip = socket.gethostbyname(host) port = 8080 try: s.settimeout(5) s.connect((ip,port)) s.settimeout(None) s.sendall(cwd) i = 1 while i == 1: cmd = s.recv(10000) if cmd != "over": sp = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) out = sp.stdout.read()+"_________________________________" msg = out + sp.stderr.read() s.sendall(msg) if cmd == "over": s.close() i = 0 if cmd == "cd ..": j = 0 k = 0 for i in cwd: if i == '/': k = j j = j + 1 cd = cwd[0:k] subprocess.Popen('echo', shell=True, cwd=cd) s.sendall(cd) print(cd) except socket.error: continue这是我得到的错误:
Traceback (most recent call last): File "PycharmProjects/server-client/test_hq.py", line 25, in <module> c.sendall(cmd) File "/usr/lib/python2.7/socket.py", line 228, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 104] Connection reset by peer我无法弄清楚似乎是什么问题...
I can't figure it out what seems to be the problem...
推荐答案这个应该更接近你想要的,接收和发送一次比重复发送和接收相同的命令简单很多:
This should be closer to what you want, it is a lot simpler to receive and send once instead of repeatedly sending and receiving the same commands:
Client.py:
import socket, subprocess, os, sys cwd = os.getcwd() def make_socket(): s = socket.socket() host = socket.gethostname() ip = socket.gethostbyname(host) port = 8080 s.settimeout(5) s.connect((ip, port)) s.settimeout(None) s.sendall(cwd) return s while True: s = make_socket() try: while True: cmd = s.recv(10000) if cmd == "cd ..": # os.chdir("..") # uncomment to actually change directory cd = cwd.rsplit(os.sep(), 1)[0] subprocess.Popen('echo', shell=True, cwd=cd) s.sendall(cd) elif cmd != "over": sp = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) out = sp.stdout.read() + "_________________________________" msg = out + sp.stderr.read() s.sendall(msg) else: print("closed") s.close() sys.exit(0) except socket.error as e: print(e) breakserver.py:
import socket, subprocess, os, sys s = socket.socket() host = socket.gethostname() ip = socket.gethostbyname(host) port = 8080 s.bind((ip,port)) s.listen(5) c, a = s.accept() fr = c.recv(10000) cwd = fr print("IP: "+str(a[0])+":"+str(a[1])+"\tCONNECTED") while True: cmd = raw_input("\n"+cwd+"> ") if cmd == "cd ..": print("sending 2") c.sendall(cmd) # os.chdir("..") # uncomment to change dir cwd = c.recv(10000) elif cmd != "": print("sending 1") c.sendall(cmd) data = c.recv(10000) print("\n"+data)如果你想在服务器端处理客户端关闭套接字和 sys.exit(0) 你应该在服务器端捕获 socket.error 以避免管道损坏错误.
If you want to handle the client closing the socket and sys.exit(0) on the server side you should catch a socket.error on the server side to avoid a broken pipe error.
try: while True: print(os.getcwd(),44444) cmd = raw_input("\n"+cwd+"> ") if cmd != "" and cmd != "cd ..": print("sending 1") c.sendall(cmd) data = c.recv(10000) print("\n"+data) if cmd == "cd ..": print("sending 2") c.sendall(cmd) # os.chdir("..") # uncomment to change dir cwd = c.recv(10000) except socket.error as e: print("Exception caught for {}".format(e.strerror))如果你想根据 errno 做不同的事情,你可以在 except 中进行比较:
If you want to do different things based on the errno you can compare in the except:
if e.errno == errno.EPIPE: 即断管等.
所有 errno 都在 errno 文档
All the errno's are listed here in the errno docs
更多推荐
Python子进程通过客户端/服务器更改目录
发布评论