소수의 매우 간단한 명령을 처리하기 위해 요청/응답 TCP 서버를 작성하려고 합니다. 나는 가능한 한 이식성을 높이고 컴파일이나 프로그래밍 언어에 대한 특정 런타임의 필요성을 피하기 위해 쉘 스크립트를 사용합니다.
나는 명령의 결과를 말하는 클라이언트에 응답하기를 원합니다. 이는 응답이 동적이어야 함을 의미합니다.
현재 다음을 사용하려고 합니다 nc
.
mkfifo commands
mkfifo nc_responses
nc -k -l 47201 >commands < <(tail -f nc_responses) &
while read -r command; do
echo "Got $command"
echo "Ran $command" >nc_responses
done <commands
이것은 두 번째 셸에서 호출한 결과입니다.
$ nc localhost 47201 <<< 'command 1'
$ nc localhost 47201 <<< 'command 2'
Ran command 1
$ nc localhost 47201 <<< 'command 3'
Ran command 2
$ nc localhost 47201 <<< 'command 4'
Ran command 3
보시다시피 응답은 요청 1보다 지연됩니다.
요청에서 응답이 동적으로 생성되도록 이 문제에 대한 해결책을 찾을 수 있는 사람이 있습니까?
(컨텍스트 - 이것은 내장 과 함께 bash
on 을 사용하고 있습니다 )macOS
macOS
nc
답변1
이 조언을 다른 곳에서도 반복하세요. https://superuser.com/a/998731
서버보다는 클라이언트에 문제가 있는 것 같습니다.
nc localhost 47201 <<< 'command 1'`
응답이 전달될 만큼 오랫동안 연결이 열려 있지 않았습니다.
이것은 작동합니다:
{ echo 'command 1'; sleep 0.1; } | nc localhost 47201
수면을 사용하는 것은 끔찍한 느낌이지만! 클라이언트가 알려진 끝점의 응답을 기다리는(시간 초과?) 더 좋은 방법이 있는지 궁금합니다.
EOF는 각 연결마다 새 입력 파이프를 열 수 없기 때문에 작업하기가 쉽지 않습니다.
답변2
질문과 관련이 없을 수도 있지만 다음을 사용하여 비슷한 것을 달성하는 또 다른 방법이 있습니다.소캇바꾸다인터넷 고양이. 명명된 파이프를 사용하거나 절전 모드를 사용할 필요가 없습니다. 자세한 내용은 socat 매뉴얼을 참조하세요.
섬기는 사람:
> socat TCP-LISTEN:5000,reuseaddr,fork SYSTEM:'read -r command \
echo "Run $command from $SOCAT_PEERADDR" >&2 \
$command'
Run date from 127.0.0.1
고객:
> socat - TCP:localhost:5000 <<<"date"
Wed Dec 22 03:37:02 PM CST 2021
그럼에도 불구하고 임의의 연결이 자유로운 명령을 실행할 수 있도록 포트를 여는 것은 결코 좋은 생각이 아닙니다.