我有一个客户端 - 服务器模型,客户端将不断检查日志文件,一旦新行进入日志文件,它就会将该行发送到服务器。
不知怎的,我设法使用以下代码来处理这件事。
server.py
import SocketServer
class MyTCPSocketHandler(SocketServer.BaseRequestHandler):
def handle(self):
# self.request is the TCP socket connected to the client
data = self.request.recv(1024).strip()
print data
# process the data..
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPSocketHandler)
server.serve_forever()
client.py
import time
import socket
def follow(thefile):
thefile.seek(0, 2)
while True:
line = thefile.readline()
if not line:
time.sleep(0.1)
continue
yield line
def connect_socket():
HOST, PORT = "localhost", 9999
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
return sock
if __name__ == '__main__':
logfile = open("my_log.log")
loglines = follow(logfile)
for line in loglines:
sock = connect_socket()
# send data
sock.sendall(bytes(line))
每次我需要调用connect_socket()
方法发送新行时,问题就出现了。
我对这个话题很新,所以有人请让我知道有没有办法解决这个问题,一旦在客户端和服务器之间建立连接,我需要连续发送数据到服务器一次又一次地建立新的连接。
如果我只连接一次并使用相同的套接字对象发送数据,则抛出
socket.error:[Errno 32]管道破损
我遵循的一些StackOverflow链接如下所示,
我找到的一件事是
当连接的一端尝试发送数据而另一端已经关闭连接时,会发生断管。
如何在两端保持连接打开?
对于这个用例,我应该使用异步方法,如果是这样,哪个框架最匹配tornado
或twisted
?
答案 0 :(得分:0)
传输一行后,关闭客户端上的连接,但不要在服务器上关闭它。
来自the docs:
RequestHandler.finish()
在handle()方法之后调用以执行所需的任何清理操作。 默认实施不执行任何操作。
所以你也应该实现finish
并关闭套接字(self.request
)。
另一个选择是不关闭客户端上的连接:
sock = connect_socket()
for line in loglines:
# send data
sock.sendall(bytes(line))
sock.sendall(b'bye') # EOF
sock.close()
但是在这种情况下,您应该修改服务器代码并确保它可以为多个客户端提供服务,并且了解何时关闭套接字。尽管存在所有这些困难,但它仍然是做事的首选方式。理想情况下,客户端每个会话只有一个TCP连接,因为它们的建立成本很高。