usocket FAQ은 내가 이것을해야하는 방법은 socket-stream
을 읽고 end-of-file
결과를 확인하는 것입니다. 그것은 하나의 스레드가 소켓 당 활성 상태 인 경우에 작동하지만 동일한 스레드에서 여러 소켓을 처리하려고하는 경우에는 만족스럽지 않습니다.다른 쪽 끝이 단일 스레드에서 소켓 스트림을 닫았는지 어떻게 확인합니까?
내가 거기에 실제로 연결하는 네 개의 클라이언트를 가지고 있다고 가정이 연습
(defparameter *socket* (socket-listen "127.0.0.1" 123456))
(defparameter *client-connections*
(list (socket-accept *socket*)
(socket-accept *socket*)
(socket-accept *socket*)
(socket-accept *socket*)))
같은 것을 생각해 보자. 연결이 끊긴 소켓이 여전히 listen
-nil
반환하고, 활성 소켓에서 read
을 시도하기 때문에 그것은 하나 개의 스레드에서 그들을 제공에 대해 이동하는 방법처럼 보인다는,이 작동하지 않습니다 제외
(wait-for-input *client-connections*)
(loop for sock in *client-connections*
for stream = (socket-stream sock)
when (listen stream)
do (let ((line (read-line stream nil :eof)))
(if (eq line :eof)
(progn (delete sock *client-connections*)
(socket-close sock))
(handle sock line))))
같은 것입니다 메시지가없는 메시지가있는 경우 다른 메시지가 준비되어 있지 않은 경우에도 메시지가없는 소켓이있는 경우에도 은 차단되지만wait-for-intput
은 즉시 반환됩니다.
클라이언트가 잠시 동안 말을하지 않고 세 번째 클라이언트의 연결이 끊어진 상황에서는 특정 소켓 연결을 찾아서 닫는 좋은 방법이 아닌 것 같습니다. 나는 입력을 전혀하지 않고 read
블록 이후로 처음 두 클라이언트가 메시지를 보낼 때까지 스레드를 기다리게하는 것을 제외하고는 순서대로 읽어야합니다.
내가 마음에있어,하지만 어떤 결정 인터넷 검색 후 발견되지 않은 솔루션은, (우선 순위를 내림차순으로)입니다 : 읽기 경우 t
을 반환 listen
에, 그렇지 않으면 해당
- 함수는 대상의 스트림에서
end-of-file
마커를 반환합니다. (위의listen
을이 개념적 함수로 바꾸면 나머지는 그대로 쓰게됩니다) - 그렇지 않으면 여행을 유발하는 닫힌 소켓 목록을 반환하는 함수가
wait-for-input
과 같습니다. - 을 반환
wait-for-input
에, 그렇지 않으면 해당하는 함수 (필요에 따라이 경우, 내가 그들을 팝업/그들이 실제로 제안read
기술로 폐쇄하고, 가까이있는 것을 확인, 폐쇄 소켓의 목록을 반복 수) 첫 번째 닫힌 소켓으로 인해 트립이 발생했습니다. (# 2와 같지만 속도가 느립니다. 반복 당 하나의 비활성 연결을 잘라 내기 때문에) - 각 소켓 연결에서 입력을받은 시간을 추적하고 특정 시간이 지나도 관계없이 종료합니다 활동하지 않는 기간. (이 잠재적으로 주위를 더 이상 필요가 죽은 연결의 무리를 유지하는 것과 아마 어쨌든 할 싶어하지만, 일을 )
- 즉시 타임 아웃 스트림에서
read-char
을 시도하는 함수,:eof
을 만날 경우t
을 반환하고 다른 시간은unread-char
이됩니다 (시간 초과 또는 읽지 않음 후nil
을 반환). (명백하지 않은 치명적인 방식으로 쉽게 깨는 것처럼 보이기 때문에 최후의 수단이됩니다).
또한 정확히 내가 잘못 생각한 경우 그 점도 지적하십시오.
당신은 그 소켓에서'select' 이벤트 루프를 에뮬레이트하려고합니까? –
@VsevolodDyomkin - 예, 나는 "select"이벤트 루프가 무엇인지 완전히 모르겠지만 이벤트 루프를 만들려고합니다. – Inaimathi