2010-12-10 3 views
0

시놉시스 : 내 프로그램이 때때로 소켓을 통해 데이터를 보내고 싶지 않은 조건으로 실행되지만 그 소켓은 절대로 없었던 이전 명령에 대한 응답을 기다리는 동안 차단됩니다. 이 문제가 발생하면 소켓을 차단 해제하고 다시 선택하는 방법이 있습니까? 그렇지 않다면 소켓을 차단했는지 테스트하여 소켓을 닫고 새 소켓을 열 수 있습니까? (처음에는 소켓을 차단해야 함)차단 된 소켓의 차단을 해제하는 방법은 무엇입니까?

세부 사항 : 두 개의 소켓을 통해 서버에 연결하고 있습니다. 소켓 1은 일반적인 명령 통신을위한 것입니다. 소켓 2는 실행중인 명령을 중단하기위한 것입니다. 중단은 언제든지 자주 올 수 있습니다. 명령 실행이 완료 될 때까지 서버가 다시 아무것도 보내지 않는 한,

socket1 send: set command data 
socket1 read: set command ack 

보내기 및 읽기 사이에 시간이 항상있다 : 소켓 (1)를 통해 전송되는 모든 명령은 같은 응답을 가져옵니다.

진행중인 명령을 중단시키기 위해 다른 소켓을 통해 연결하고 중단 명령을 실행합니다. 그런 다음 소켓 1을 사용하여 새 명령을 실행합니다.

중단 요청이 프로그램을 멈추고 난 후 때때로 소켓 1을 통해 실행되는 명령을 발견했습니다. 소켓 1은 이전에 발행되지 않은 명령에 대한 응답을 기다리지 못하게 차단 된 것처럼 보입니다. 보통 때로는 작동하지 않지만 (서버를 작성하지 않았습니다).

이러한 경우, 소켓 1이 읽기를 기다리는 것이 차단되었는지 확인할 수있는 방법이 있습니까? 그렇다면 읽기 및 이동을 포기 하시겠습니까? 아니면 전혀 검사 할 방법이있어서 소켓을 닫고 다시 시작할 수 있습니까?

xx!

업데이트 1 : 답변 해 주셔서 감사합니다. 왜 내가 블로킹 소켓을 사용하는지에 관해서는,이 코드로 CNC-type 머신을 제어하고 있기 때문에 실행을 요청한 명령어가 언제 실행되는지를 알아야하기 때문입니다. 서버가 완료되면 ACK를 반환하므로 처리하는 데 좋은 방법 인 것 같습니다. 비 차단을위한 리팩토링에 대한 아이디어가 마음에 들지만 명령이 다르게 수행 될 때 정보를 얻는 방법을 상상할 수는 없습니다. 선택 및 기타 옵션을 살펴 보겠습니다.

+0

에 대한 답변을 살펴보십시오. 나는 소켓을 플러시하고, 파일 설명자 (makefd()를 통해)를 사용하고 있다고 언급 했어야합니다. – mix

+1

나는 Martin과 Karl의 대답을 좋아한다. 또 다른 가능성은'socket.settimeout'을 사용하는 것인데, 이것은 소켓 조작을 차단하게하지만 잠시 동안 만 차단합니다. –

+0

사실 나는이 질문을 아주 잘 이해하고 있는지 확신 할 수 없다. 당신은 당신의 소켓이 "차단"되었다고 말합니다. 다른 스레드가 실제로 소켓에서'recv' 호출로 현재 차단 되었기 때문입니까? 즉, 한 번에 소켓을 사용하려고하는 여러 스레드가 있습니까? 그렇지 않다면 왜 소켓이 차단되었다고 생각합니까? 소켓에 적용 할 때 일반적으로 "차단됨"이라는 단어를 생각하지 않기 때문에 조금 혼란 스럽습니다. 블로킹 또는 비 블로킹 동작을 가졌지 만 실제로 차단 된 스레드입니다. (그렇지 않다면, 이것은 좋은 질문입니다, fwiw.) –

답변

4

불쾌감을주는 것은 아닙니다만, 블로킹 소켓이 필요하다고 말하면서 비 블로킹 소켓이 필요한 아주 좋은 이유를 설명합니다. non-blocking을 사용하도록 리팩토링을 추천합니다.

그 외에도 소켓 차단 여부를 알고있는 유일한 방법은 프로그램이 recv 또는 변형 중 하나이며 아직 반환하지 않았다는 것입니다. 다른 사람이 내가 알지 못하는 API를 알고있을 수도 있지만 recv 호출 전에 '차단 된'부울을 설정하고 나중에 지우면 가장 좋은 해킹 정보 일 것입니다. 그러나 당신은 그것을하고 싶지 않습니다. 날 믿어 라, 리팩토링은 결국 가치가있을거야.

2

이 문제에 대한 전통적인 해결책은 select을 사용하는 것입니다. 작성하기 전에 소켓이 쓰기를 지원하는지 테스트하고, 그렇지 않을 경우 다른 작업 (예 : 응답 대기)을 수행하십시오. select보다 한 레벨 위의 Python은 이러한 처리를 가능하게하는 asyncore 모듈을 제공합니다. 위의 두 레벨 인 Twisted은 메시지의 비동기 처리를 다루는 전체 프레임 워크입니다.

0

소켓은 전이중이어야합니다. 파이썬이 다른 쓰레드가 같은 소켓에서 읽는 동안 쓰레드가 쓰레드를 쓰지 못하도록 차단했다면 나는 그것을 파이썬의 주요 버그로 간주 할 것이다. 이것은 내가 사용한 다른 프로그래밍 언어에서는 발생하지 않습니다.

0

select() 또는 poll()에서 실제로 무엇을 차단해야할까요? 차단 된 소켓의 차단을 해제하는 유일한 방법은 허용되지 않는 데이터 또는 신호를 수신하는 것입니다. select() 또는 poll() 호출은 읽기 또는 쓰기 (버퍼 공간 대기 중)에서 하나 이상의 소켓 대기를 차단할 수 있습니다. 주기적으로 기다려 다른 것들을 확인하고 싶다면 시간 초과도 걸릴 수 있습니다. Block Socket with Unix and C/C++ Help

관련 문제