2016-10-19 3 views
0

클라이언트가 지속적으로 로그 파일을 검사하는 클라이언트 - 서버 모델이 있으며 새 줄이 로그 파일에 들어 오면 해당 줄을 서버에 보냅니다.tcp python 소켓 영원한 연결 유지

어쨌든 다음 코드를 사용하여이 문제를 해결할 수있었습니다.

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] Broken pipe

나는 아래와 같습니다 따랐다 일부 StackOverflow의 링크를 던지고 데이터를 전송하기 위해 동일한 소켓 객체를 사용하고있는 경우,

1, 2, 내가 찾은 3

한 가지

Broken Pipe occurs when one end of the connection tries sending data while the other end has already closed the connection.

,369입니다

양쪽 끝에서 연결을 어떻게 열어 둘 수 있습니까? 이 유스 케이스의 경우 비동기 메서드를 사용해야하고 어떤 프레임 워크가 가장 일치하는 tornado 또는 twisted이 될까요?

+0

TCP 소켓 서버가 스레드 소켓 서버가 아닙니다. 대부분의 에러는'time.sleep()'는 매우 나쁜 생각입니다. 서버가 ACK (지연 필요 없음)에 대한 응답을 필요로합니다. 코드에 이더넷 프로토콜이 없습니다. 실제 스켈레톤을 만들면 0.5 밀리 초 패킷이 성공합니다. 소켓은 단방향 시스템이 아니므로 모든 패킷에서 하드웨어 버퍼를 지울 수 없습니다.제 생각에는 복잡한 프로젝트가 아닌'WSGI'가 사용됩니다. [이 항목 확인] (https://docs.python.org/2.7/library/wsgiref.html) – dsgdfg

답변

0

줄을 전송 한 후에는 클라이언트에서 연결을 닫지 만 서버에서는 닫지 마십시오. the docs에서

:

RequestHandler.finish()

Called after the handle() method to perform any clean-up actions required. The default implementation does nothing.

그래서 당신은뿐만 아니라 finish를 구현하고있다 소켓 ( self.request)을 닫아야합니다.


또 다른 옵션은 클라이언트의 연결이 종료되지 않습니다 : 서버 코드를 수정하고 여러 클라이언트를 제공 할 수 있는지 확인해야합니다,이 경우 그러나

sock = connect_socket() 
for line in loglines: 
    # send data 
    sock.sendall(bytes(line)) 
sock.sendall(b'bye') # EOF 
sock.close() 

을 종료 할 때 그것은 이해 소켓. 이러한 모든 어려움에도 불구하고 일을하는 것이 바람직한 방법입니다. 이상적으로 클라이언트는 설정하는 데 비용이 많이 드는 세션 당 하나의 TCP 연결을 가지고 있습니다.