단일 프로세스를 활용하여 TCP 통신을 할 때엔 하나의 프로세스가 하나의 클라이언트만 받았다.
그도 그럴것이 TCP의 정의 자체가 (IP + Port)간의 신뢰성 있는 데이터 전달이기 때문에 다른 클라이언트의 연결 및 데이터 통신을 적어도 Close되지 않는다면 받아들이지 않는다.
그렇기 때문에 다음과 같이 listening socket으로 듣고, listening queue에 저장한 해 둔 다음 차례대로 연결을 하는 것이다.
실제 실행
그렇다면 TCP 통신을 사용하면서도 다중 Client와 통신할 순 없을까?
답은 "가능하다"이다. 하지만 하나의 프로세스(포트)로는 불가능 하므로 자식 프로세스를 생성하고 그 자식 프로세스들이 통신하게 하면 된다.
이전의 통신이 어떻게 이루어지는지 잠시 확인해 보면, 주소와 포트와 프로토콜 등 상대방의 연결을 위한 정보를 명시하고, 그 정보를 바탕으로 소켓을 열면 파일과 같이 읽고 쓸 수 있게되고, 프로세스는 그를 파일디스크립터로써 읽고 씀으로써 통신할 수 있는것이다.
이렇게 열린 연결을 folk를 통해 복사하여 자식 프로세스가 클라이언트와 통신하게 하고 부모 프로세스는 자식프로세스를 생성한 후 바로 close를 해버림으로써 또 다른 연결을 받을 수 있는 것이다.
listening queue에는 listening socket을 통해 생성된 socket들이 대기를 하고 있을 것이고, 부모프로세스가 accept()을 하면 서비스 소켓(client socket)이 될 것이다.
즉, listening socket -> listen을 위한 socket, connecting socket -> connect를 위한 socket
하지만 하나의 서버는 하나의 클라이언트와 연결되어있어야 하므로 부모프로세스의 입장에서 보았을 땐 연결과 자식프로세스 생성 직후 그 connect를 끊어야 하는 것이고 자식 프로세스 입장에서 보았을 땐 listening socket과 queue를 close 해야하는것이다.
그렇게 하면 다음과 같이 나올 것이다.
다음은 실제 코드의 적용이다.
이것의 문제도 분명 존재한다. folk와 dup으로 생긴 자식프로세스는 실행이 종료되더라도 좀비프로세스로써 남아있게 된다. 그 이유는 사실 명확한데 부모 프로세스가 자식 프로세스에 대한 정보를 얻기 위해서는 프로세스를 남겨놔야 하기때문이다 (프로세스를 그대로 종료시키면 정보가 소실되므로!). 그리고 그 정보를 부모프로세스가 요청하고 받고나서야지 자식프로세스는 정상적으로 종료가 되는것이다.
자식프로세스 종료까지 대기 + 자식프로세스가 끝나고 남긴 정보를 리턴 요청을 담당하는 함수가 wait이다.
하지만 이 함수를 무작정 실행시키면 자식프로세스가 종료되기를 기다리게 되고 이는 자식프로세스를 통한 다중 클라이언트 통신을 할 수 없게되므로 자식 프로세스가 종료 될 때에 wait을 실행시킴으로써 멀티 클라이언트 TCP 통신 + 좀비프로세스 삭제 를 해줄 수 있다.
기본적으로 자식 프로세스가 종료되면 부모 프로세스로 SIGCHLD시그널이 오는데, 이 시그널을 핸들링하는 핸들러에 wait함수를 포함하면 좀비프로세스가 지속되지 않게 된다.
'학교 공부 > 네트워크' 카테고리의 다른 글
Multiplexing을 통한 싱글 프로세스의 다중 클라이언트 연결 (0) | 2021.04.14 |
---|---|
세마포어, 뮤텍스를 활용한 공유 자원 제어 (0) | 2021.04.14 |
멀티 쓰레드를 활용한 멀티 클라이언트 TCP 통신 (0) | 2021.04.14 |
네트워크 프로그래밍 (VM의 NAT와 Bridge, UDT) (0) | 2021.04.01 |