[英]conn.send('Hi'.encode()) BrokenPipeError: [Errno 32] Broken pipe (SOCKET)
[英]BrokenPipeError: [Errno 32] Broken pipe for makefile socket?
我已经制作了一个套接字,我需要将 C 文件中的一些标准输出数据通过以太网传输到我的计算机。 它工作正常,直到我关闭客户端的连接,然后我在服务器套接字上收到以下错误:
Traceback (most recent call last):
File "/home/pi/Documents/av/network/server_socket.py", line 82, in <module>
main()
File "/home/pi/Documents/av/network/server_socket.py", line 67, in main
sf.write(line.rstrip())
File "/usr/lib/python3.9/socket.py", line 722, in write
return self._sock.send(b)
BrokenPipeError: [Errno 32] Broken pipe
我希望 go 的套接字在客户端关闭连接时重新接受新连接。 我尝试阅读 python 套接字文档,但找不到任何关于该问题的信息。 我可以向服务器发送“退出”消息 - 但我宁愿服务器忽略 pipe 已关闭并返回接受新连接。
我有我的服务器代码(我在服务器上收到错误。我已通过将其包装在 ## ISSUE IS HERE ## 中来概述问题):
import socket
import time
import os
import subprocess
# start server and wait for connections
def startServerSocket(PORT):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', PORT)) # bind loopback addr
sock.listen(2)
return sock
# initiate the ethernet protocol and log client to /var/log/pythonconnection.log
def readyConnection(conn, addr):
# send request to get incoming connection host name
data = "whoisthis".encode()
conn.sendall(data)
# await with blocking recv for client response and log response
data = conn.recv(1024)
# need to be logged
print("\nConnected to " , data.decode(), " as ", addr[0], " at [", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), "]")
# tell that we're ready to start stream
data = "ready".encode()
conn.sendall(data)
# get response saying client is ready to rec
data = conn.recv(1024)
if (data.decode()=="ready"):
return True
return False
def main():
sock = startServerSocket(4000)
print("waiting for connection... ")
while True:
conn, addr = sock.accept()
# create serverfile to transmit IO signals to client via stream
sf = conn.makefile("wrb", buffering=0)
# connection function
connection = readyConnection(conn, addr)
if (connection):
print("[0/2] -> Valid connection established")
print("[1/2] -> Printing stream to socket")
# start reading from stdout in subprocess
proc = subprocess.Popen(
["/home/pi/Documents/av/sonar/a.out"],stdout=subprocess.PIPE)
while True:
line = proc.stdout.readline() # read one stdout line
if not line:
break
## ISSUE IS HERE ##############
sf.write(line.rstrip()) # write line to socket file
## ISSUE IS HERE ##############
sf.flush() # force line to be sent immediately
sf.close()
conn.close()
print("[x/x] -> Client has closed connection or stream reached EOF")
if __name__ == '__main__':
main()
我的客户代码:
import socket
import time;
# function to setup and try to connect to a server
def connect(HOST, PORT):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT)) # raspberry pi addr + allowed port
return sock
def handleRequest(data):
output = ""
if (data=="whoisthis"):
output = socket.gethostname()
print("-> Connecting as ", output)
if (data=="ready"):
print("-> Socket ready for IO")
output = "ready"
return output
def main():
sock = connect('123.123.1.69', 4000)
cf = sock.makefile("wrb", buffering=0)
while True:
data = sock.recv(40).decode()
handler = handleRequest(data)
print(data.strip()+"\n")
if (handler.strip() != ""):
if (data.strip()=="ready"):
sock.sendall("ready".encode()) # tell we're also ready to stream
break ## exit loop
sock.sendall(handler.encode())
time.sleep(0.1) # just sleep while testing
# ready to recieve stream via ethernet
print("-> ready to stream")
while True:
print(cf.read(64).decode()) # read 64 bytes at a time
time.sleep(0.1)
if __name__ == '__main__':
main()
Edit: I've also tried the select library for I/O based on https://docs.python.org/3/library/select.html where i just copied some code from https://stackoverflow.com/a/ 21802953/15386210
我通过使用 BrokenPipeError 添加 try/except 来包装 makefile 写入方法解决了这个问题。 对于未来的任何人来说,这里是解决故障管道问题的代码:
proc = subprocess.Popen(
["/home/pi/Documents/av/sonar/a.out"],stdout=subprocess.PIPE)
while True:
line = proc.stdout.readline() # read one stdout line
if not line:
break
try:
sf.write(line.rstrip()) # write line to socket file
except (BrokenPipeError, IOError):
print("an errror aka client disconnect")
break
sf.flush() # force line to be sent immediately
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.