fork 이후 소켓 close했지만 커넥션이 종료되지 않는다.

jin942002·2022년 7월 4일
0

상황

fork 이후 부모 프로세스에서 소켓을 close했지만, 커넥션이 종료되지 않는다.

코드:

for (;;) {
        struct sockaddr_storage addr;
	socklen_t addrlen = sizeof addr;
	int sock;
	int pid;

	sock = accept(server_fd, (struct sockaddr*)&addr, &addrlen);
	if (sock <0) log_exit("accept(2) failed: %s", strerror(errno));
	pid = fork();
	if (pid < 0) exit(3);
	if (pid == 0) {
	    FILE *inf = fdopen(sock, "r");
	    FILE *outf = fdopen(sock, "w");

	    service(inf, outf, docroot);
	    exit(0);
	}
	close(sock);
}
  1. fork를 할 때 자식 프로세스가 생성된다.
  2. 두 프로세스에서 모두 fork 이후의 코드가 실행된다.

위 코드에 로그와 sleep을 추가했다.

if (pid == 0) {

    FILE *inf = fdopen(sock, "r");
    FILE *outf = fdopen(sock, "w");

    service(inf, outf, docroot);
    log_info("wrote response done!");
    sleep(15);
    exit(0);
}
log_info("closing socket...");
close(sock);
log_info("closing socket done!");

기대 상황:
closing socket done! 이 출력된 시점에서 커넥션은 종료되어야 한다.

실제:
closing socket done! 이 출력되도 커넥션은 유지된다.
자식 프로세스에서 15초간 sleep한 후 exit을 해야 커넥션이 종료된다.

이유:
자식 프로세스에서 소켓 file descriptor를 참조하고 있기에, 부모 프로세스에서 소켓을 close하더라도 커넥션이 종료되지 않는다.

소켓을 참조하는 모든 fd를 close해야 한다.
위에서 자식 프로세스는 아직 소켓을 참조하고 있으므로, 부모 프로세스에서 close하더라도 커넥션이 종료되지 않았다.

https://stackoverflow.com/questions/31467768/how-to-correctly-use-socket-close-for-fork
https://stackoverflow.com/questions/6014055/how-is-socket-connection-being-handled-in-a-forked-process

0개의 댓글