나는 tcp 소켓에서 문자열을 읽고 인코딩된 뷰를 출력하는 xinetd를 사용하여 간단한 웹 서비스를 만들었습니다. 원시 바이너리(qrencode)는 표준 입력만 읽습니다.
netcat
as와 함께 사용하면 잘 작동합니다.echo string | nc <ip> <port>
하지만 bash tcp 리디렉션을 통해 사용하려고 하면 응답하지 않습니다.
exec 7<>/dev/tcp/<ip>/<port>
echo string >&7
cat <&7
영원히 기다립니다. 나는 이 fd에 \004, cat /dev/null을 에코하려고 시도했지만 성공하지 못했습니다. 어떻게 작동하게 할 수 있나요?
답변1
서비스 inetd
또는 귀하의 서비스가 EOF를 기다리고 있을 수 있으며, 그런 다음 종료합니다(그런 다음 연결을 닫습니다).
이렇게 하려면 클라이언트가 소켓의 송신측을 닫고 수신측은 계속 열어두어야 합니다. 이것이 nc
표준 입력에서 EOF를 감지할 때 수행되는 작업입니다.
/dev/tcp/host/port
가상 인터페이스( bash
ksh에서 복사됨)는 이를 허용하지 않습니다. zsh
보다 유연한 대안 이라도 ztcp
연결을 비대칭적으로 닫을 수는 없습니다.
대신 시간 초과를 사용할 수도 있지만 이는 신뢰할 수 없습니다. 따라서 nc
또는 같은 전용 유틸리티를 계속 사용 socat
하거나(유사한 인터페이스를 갖기 위해 coproc 사용) 적절한 네트워크 API(coproc에 대한 인터페이스 포함 shutdown()
) 가 있는 프로그래밍 언어를 사용하는 것이 좋습니다 .
^D
선 규칙이 icanon
모드(대략적인 선 편집기 구현)에 있을 때 0x04 문자( )는 단순히 최종 장치의 EOF를 나타냅니다. 따라서 이것이 작동하려면 xinetd
서비스에서 생성된 소켓 사이에 의사 터미널을 삽입해야 합니다. 예를 들어 다음과 같이 시작합니다.
socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3
바꾸다
your-service
그런 다음 다음을 보내야 합니다.
printf 'text\n\4' >&7
또는:
printf 'text\4\4' >&7
서비스에서 입력의 끝을 볼 수 있습니다.
행 편집기로 인해 your-service
개행 또는 문자를 전송하는 경우에만 입력을 볼 수 있습니다 ^D
( 위의 , , werase
, erase
... 처리 도 의 일부로 비활성화됨 ).kill
^C
^Z
raw
따라서 0x4 문자에서 종료하는 대신 입력 전처리기를 삽입할 수도 있습니다. 예를 들면 다음과 같습니다.
awk -v RS='\4' -v ORS= '{print; exit}' | your-service
(전체 버퍼 또는 eof가 수신되지 않는 한 입력을 처리하지 않을 awk
수 없습니다 .)mawk
mawk
답변2
서비스가 설정된 TCP 세션을 닫지 않으면 클라이언트 연결을 중지하는 것 외에는 다른 방법이 없는 것 같습니다. 예를 들어 timeout 명령을 사용합니다.
timeout 1 cat <&7
echoing \004, cat /dev/null
또한 시도하는 다른 명령( )은 다른 셸에서 실행하기 때문에 실패할 가능성이 높습니다. 파일 설명자 7은 첫 번째 쉘을 실행하는 쉘에 연결되어 있으므로 exec 7<>/dev/tcp/<ip>/<port>
첫 번째 쉘 내에서만 상호 작용할 수 있습니다.