我有一个小型服务器程序,它接受TCP或本地UNIX套接字上的连接,读取一个简单的命令,并根据命令发送一个回复.问题是客户端有时可能对答案没兴趣并且提前退出,因此写入该套接字将导致SIGPIPE并使我的服务器崩溃.什么是防止崩溃的最佳做法?有没有办法检查线的另一边是否还在读?(select()似乎在这里不起作用,因为它总是说套接字是可写的).或者我应该用处理程序捕获SIGPIPE并忽略它?
目前我正在使用python内置的应用程序.当我在个人计算机上运行时,它可以正常工作.
但是,当我将它移动到生产服务器时.它不断向我显示如下错误:
我做了一些研究,我得到了最终用户浏览器在服务器仍在忙于发送数据时停止连接的原因.
我想知道它为什么会发生以及阻止它在生产服务器中正常运行的根本原因是什么,而它可以在我的个人计算机上运行.任何建议表示赞赏
Exception happened during processing of request from ('127.0.0.1', 34226)
Traceback (most recent call last):
File "/usr/lib/python2.7/SocketServer.py", line 284, in
_handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 310, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python2.7/SocketServer.py", line 641, in __init__
self.finish()
File "/usr/lib/python2.7/SocketServer.py", line 694, in finish
self.wfile.flush()
File "/usr/lib/python2.7/socket.py", line 303, in flush
self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用套接字将指令从 Django 网站发送到机器人(Raspberry Pi),但每当我尝试从网站发送第二条指令时,都会出现错误。如果您知道造成此问题的原因,那么帮助将是惊人的!网站发送查看:
def form_valid(self, form, **kwargs):
robo_pk = self.kwargs['pk']
robo = Robot.objects.get(pk=robo_pk)
PORT = robo.port
SERVER = robo.server
ADDR = (SERVER, PORT)
self.object = form.save()
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
def send(msg):
message = msg.encode(FORMAT)
msg_length = len(message)
send_length = str(msg_length).encode(FORMAT)
send_length += b' ' * (HEADER - len(send_length))
client.send(send_length)
client.send(message)
send(form.cleaned_data['path_options'])
send("MESSAGE SENT :) !")
send(DISCONNECT_MESSAGE)
return render(self.request, "dashboard-home/thank-you.html")
Run Code Online (Sandbox Code Playgroud)
错误回溯:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 865, in …Run Code Online (Sandbox Code Playgroud) 我在这里要做的是使用PIL将Tkinter Canvas的内容保存为.png图像.
这是我的保存功能('graph'是画布).
def SaveAs():
filename = tkFileDialog.asksaveasfilename(initialfile="Untitled Graph", parent=master)
graph.postscript(file=filename+".eps")
img = Image.open(filename+".eps")
img.save(filename+".png", "png")
Run Code Online (Sandbox Code Playgroud)
但它得到了这个错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\Users\Adam\Desktop\Graphing Calculator\Graphing Calculator.py", line 352, in SaveAs
img.save(filename+".png", "png")
File "C:\Python27\lib\site-packages\PIL\Image.py", line 1406, in save
self.load()
File "C:\Python27\lib\site-packages\PIL\EpsImagePlugin.py", line 283, in load
self.im = Ghostscript(self.tile, self.size, self.fp)
File "C:\Python27\lib\site-packages\PIL\EpsImagePlugin.py", line 72, in Ghostscript
gs.write(s)
IOError: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)
我在Windows 7,Python 2.7.1上运行它.
我该如何工作?
我刚刚了解了 SIGPIPE,然后阅读了如何在 Python 中处理这些。
在其他来源中,我读过:如何在 python 中处理损坏的管道 (SIGPIPE)?
假设管道读取脚本退出,那么所有答案都表明写入脚本将其写入调用包装在 try 子句中。
但是,我无法完成这项工作。这是我的代码:
# printer.py
import time
try:
for i in range(10):
time.sleep(1)
print i
except:
print 'We caught the problem'
Run Code Online (Sandbox Code Playgroud)
和
#nonreader.py
#read nothing, but stay alive for 5 sec
import time, sys
time.sleep(5)
sys.exit(0)
Run Code Online (Sandbox Code Playgroud)
在外壳中:
$ python printer.py | python nonreader.py
close failed in file object destructor:
Error in sys.excepthook:
Original exception was:
Run Code Online (Sandbox Code Playgroud)
很明显,什么都没抓到。此外,当它打印“原始异常是:”时,它看起来真的错了,然后就没有了。
有什么问题/我误解了什么?
托马斯
在这篇文章之后,我可以将tail -f日志文件发送到网页:
from gevent import sleep
from gevent.wsgi import WSGIServer
import flask
import subprocess
app = flask.Flask(__name__)
@app.route('/yield')
def index():
def inner():
proc = subprocess.Popen(
['tail -f ./log'],
shell=True,
stdout=subprocess.PIPE
)
for line in iter(proc.stdout.readline,''):
sleep(0.1)
yield line.rstrip() + '<br/>\n'
return flask.Response(inner(), mimetype='text/html')
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()
Run Code Online (Sandbox Code Playgroud)
这种方法有两个问题。
tail -f log关闭网页后,该过程将持续存在。访问http://localhost:5000/yield n 次后会有 n 个 tail 进程我的问题是,是否可以让flask在有人访问页面时执行shell命令,并在客户端关闭页面时终止该命令?就像Ctrl+C之后tail -f log。如果没有,还有哪些替代方案?为什么我一次只能有 1 个客户端访问该页面?
注意:我正在研究启动/停止任意 shell 命令的一般方法,而不是特别尾随文件
python ×5
broken-pipe ×2
sigpipe ×2
c ×1
flask ×1
io ×1
linux ×1
networking ×1
pipe ×1
python-3.x ×1
raspberry-pi ×1
signals ×1
sockets ×1
subprocess ×1
tkinter ×1