2016-08-26 1 views
0

나는 여기서 멍청한 녀석이지만, 소켓을 폴링 할 수있는 스크립트를 설정하려고 시도하고 소켓 데이터가 전송되지 않으면 루프가 계속 실행되고 다른 일을한다. select()를 사용하여 찾은 몇 가지 예제를 가지고 놀았지만 코드를 구성하는 방법에 관계없이 server.recv() 행 또는 그 근처에서 멈추고 응답을 기다리는 것처럼 보입니다. 클라이언트가 데이터를 보내지 않았거나 클라이언트 연결이없는 경우이 작업을 건너 뛰고 싶습니다.Python Sockets Select가 걸려 있습니다 - 소켓 데이터를 기다리는 동안 다른 작업을 수행합니까?

차이점이 있으면이 응용 프로그램에서는 서버 스크립트가 응답 데이터를 보내지 않아도됩니다.

실제 응용 프로그램은 루프를 실행하고 일부 LED에 애니메이션을 적용하는 것입니다.이 LED는 라스베리 파이의 I/O에 대한 루트 액세스가 필요합니다. 이 스크립트 데이터를 애니메이션을위한 제어 매개 변수를 전달하는 소켓을 통해 다른 별도의 스크립트에서 전송할 것입니다. 이렇게하면 외부 스크립트에 루트 액세스가 필요하지 않습니다.

지금까지 데이터를 보내고받는 것이 효과적이었습니다. 나는 들어오는 데이터가 없을 때 회전을 유지할 루프를 얻을 수 없습니다. 이것이 select()가 허용하려고했던 것이지요. 그러나 발견 한 예제는 그런 식으로 작동하지 않는 것 같습니다.

server.setblocking (0)을 추가하려고 시도했지만 아무 소용이 없습니다. (올바르게 데이터를 보내지 않은 경우 non-blocking 인스턴스는 코드가 recv()를 건너 뛸 수 있도록 허용해야하지만이 경우에는 해제 될 수 있습니다.) 다음 http://ilab.cs.byu.edu/python/select/echoserver.html

클라이언트 측 스크립트 다음에 서버 측 스크립트입니다

여기 예를 들어 내 코드를 기반으로했다.

서버 코드 :이 예에 의해 달성하고자하는 어떤

#!/usr/bin/python   # This is client.py file 

import socket    # Import socket module 

s = socket.socket()   # Create a socket object 
host = socket.gethostname() # Get local machine name 
port = 20568    # Reserve a port for your service. 

s.connect((host, port)) 

data = "123:120:230:51:210:120:55:12:35:24" 
s.send(data) 
print s.recv(1024) 
s.close      # Close the socket when done 

보고있다 skclient.py 반복 "루핑"

#!/usr/bin/env python 

import select 
import socket 
import sys 

server = socket.socket() 
host = socket.gethostname() 
port = 20568 
size = 1024 
server.bind((host,port)) 
server.listen(5) 
input = [server,sys.stdin] 
running = 1 
while running: 
    inputready,outputready,exceptready = select.select(input,[],[]) 

    for s in inputready: 

     if s == server: 
      # handle the server socket 
      client, address = server.accept() 
      input.append(client) 

     elif s == sys.stdin: 
      # handle standard input 
      junk = sys.stdin.readline() 
      running = 0 

     else: 
      # handle all other sockets 
      data = s.recv(size) 
      if data: 
       s.send(data) 
      else: 
       s.close() 
       input.remove(s) 
    print "looping" 
server.close() 

는 클라이언트 코드 sockselectserver.py 영원히, 클라이언트 스크립트가 데이터를 보내면 그 데이터 프린트를보고, 반복적으로 반복되는 "루핑"재개를보십시오. 그게 내가 의도 한대로하고 있다는 것을 말해 줄거야.

필자가 테스트 할 때마다 클라이언트를 실행할 때마다 "루핑"이 화면에 3 번 인쇄 된 것을 볼 수 있습니다. 나는 select 내부에서 어떤 일이 일어나고 있는지 완전히 이해하지 못한다. 그러나 나는 단지 1 시간 만 출력한다고 생각한다.

입력 위치 .. 다른 곳으로 select.select()를 이동했지만 시도 할 때마다 호출해야하는 것으로 나타났습니다. 그렇지 않으면 서버가 응답을 멈 춥니 다 (예 : 끝없는 while : 루프).

나는 이것이 제작자 수업에서 다른 해커 유형에 대해 가르 칠 수있을만큼 간단 할 수 있기를 바라고 있으며, 그래서 나는 멀티 스레딩과보다 정교한 솔루션으로 너무 정신 나갈 필요가 없길 희망한다. . 최후의 수단으로 외부 스크립트에서 mySQL에 모든 매개 변수를 로깅 한 다음이 스크립트를 사용하여 테이블에서 다시 쿼리하는 방법을 고려하고 있습니다. 나는 거기에서 경험을 쌓았을 것이고 아마도 작동 하겠지만,이 소켓 앵글은 좀 더 직접적인 해결책이 될 것 같습니다.

도움을 주시면 감사하겠습니다.

+0

서버가 자체 루프가되어야합니다. – YOU

+0

빠른 답장을 보내 주셔서 감사합니다. 어떻게 구현할지 모르겠습니다. 예제 코드 스 니펫을 공유 할 수 있습니까? 모든 것을 하나의 루프로 감쌀 것인가? 그렇다면, 다른 함수 (클라이언트가 들어오는 데이터를 보낼 때만 반복해서 호출되는 함수)가 어디에서 호출 될까? – kjav

+0

'select.select (input, [], [], 1)'옵션에서'select.select()'를 timeout (초) 옵션으로 호출 해보십시오. – acw1668

답변

0

그레이트 뉴스. 이것은 쉬운 수정이었고 누군가 다른 사람이 필요로 할 경우를 대비하여 게시하고 싶었습니다. 위의 acw1668로부터의 제안은 나를 가게했다.

inputready,outputready,exceptready = select.select(input,[],[],0) 

이것은 파이썬 문서에 있지만 어떻게 든 나는 그것을 놓친 :

단순히이 같은 select.select()에 "0"의 시간 제한을 추가했다. 여기 링크 : 워드 프로세서 당 https://docs.python.org/2/library/select.html

: 은 "옵션 timeout 인수는 초 부동 소수점 숫자로 제한 시간을 지정하는 타임 아웃 인수가 적어도 하나 개의 파일 기술자가 준비 될 때까지 기능 블록을 생략 할 때를.. 시간 제한 값이 0이면 폴링을 지정하고 차단하지 않습니다. "

위의 코드와 동일한 코드를 테스트하고 print "루핑"행 직후 time.sleep (5)를 사용하여 5 초의 지연을 추가했습니다. 지연으로 인해 데이터 또는 클라이언트가 없으면 코드는 단지 5 초마다 반복되고 화면에 "루핑"을 인쇄합니다. 5 초 동안 클라이언트 스크립트를 시작하면 일시 중지되고 다음에 5 초 지연이 끝날 때 메시지가 처리됩니다. 때로는 매우 다음 루프가 아니라 다음 루프에 응답합니다. server.accept를 처음 실행할 때 다음에 s.recv()를 통해 실제로 데이터를 교환하기 때문에 이것이라고 가정합니다.

관련 문제