TCP커넥션이 일방적으로 끊겼을때 서버에서의 계속적인 select문

iamsjkim의 이미지

server에서는 select를 돌리고 client가 접속을 하도록 프로그래밍했습니다.
(아래코드 참조. 리눅스 gcc환경)

모.. 일단 client가 접속을 해서 connection맺고 통신은 잘 하는데요..
client가 정상적으로 종료(프로그램에서는 'exit'을 치면 client는 자동으로 종료하고 그 메세지를 server에 날려서 server가 그 메세지를 받으면 해당 client의 connection을 끊어버리는.. 전형적인 채팅프로그램으로 짜여져있습니다.)하지 않고 비정상적으로 종료(예를 들어 Ctrl+C로 종료)했을 경우 select문 바로 앞에 있는 프린트문이 무한대로 출력이 됩니다-_-
아무래도 비정상적으로 종료한 client를 계속 참조하느라 그런건지..(잘은 모르겠지만요)

이 경우 client가 비정상적으로 종료를 하더라도 server에서 해당 client를 더이상 상관안하고 server가 안정적으로 돌아가도록 하는 방법이 없을까요?

...
(생략)

	FD_ZERO(&allset);
	FD_SET(0,&allset);
	FD_SET(server_fd, &allset);
	FD_SET(fd,&allset);

	while(1)
	{
		printf("RG is waiting for message...\n");

		FD_ZERO(&read_fds);
		read_fds = allset;
		timeout.tv_sec =5;

		if ((nready=select(max_fd+1, &read_fds, NULL,NULL, &timeout))< 0)
			{ printf("Select() failed...\n");	}

							/* TCP connection request */
							if (FD_ISSET(server_fd, &read_fds))
							{
								clilen = sizeof(client_addr);
								if ((client_fd=accept(server_fd, (struct sockaddr *) &client_addr, &clilen)) != -1)
								{	printf("Server : client connected.\n");	}
								else {	printf("Server : client connection failed...\n");
										return -1;	}

..........().....................

dhjung의 이미지

말씀하신 대로라면, 아래 처리가 미흡한듯 한데요..

1. 에러가 발생한 소켓에 대한 에러처리
2. 소켓 close()
3. read_fds에서 제거


--------------------------
Donghyun Jung

FruitsCandy의 이미지

클라이언트에서 세션을 물고 있다는 것을 주기적으로 확인하는 방법을

쓰시면 해결 될거 같습니다.

예를 들어 클라이언트 쪽에서는 30초 를 주기로

'나살아있다'는 패킷을 보내주고 , 서버에서는 그 패킷을 확인합니다.

만약 select 타임아웃을 30초로하고 30초가 넘어서 '나살이있다'는 패킷을

못받으면 소켓 통신이 끊긴 것으로 간주하고 해당 클라이언트를

끊어 버리시면 됩니다.

아지랑이류 초환상 공콤 화랑... 포기하다.. T.T