소켓 프로그램에서 클라이언트 프로세스만 강제적으로 종료시키면 서버쪽에서 '0'값을 받던데요...
그런데 클라이언트의 컴퓨터를 강제적으로 꺼 버리면 서버쪽에서 recv 함수가 아무것도 받지 못하고 계속적으로 기다리던데...
서버쪽에서 클라이언트의 컴퓨터가 강제적으로 꺼 졌음을 recv 함수를 통해 알 수 있는 방법이 있나요...
close에는 두가지의 유형이 있습니다. graceful close, strongly close...
후자의 경우엔 close와 관련된 FIN Sync packet이 상대방에게 전달되지 않게 됩니다.
보통 이러한 close를 감지하기 위해서 서버사이드에서 쓰이는 기법은 time stamping입니다.
time stamping을 하는 루틴은 보통 일정 시간[보통 1초 혹은 select 루틴에서 루틴이 끝나고 난뒤에.. <-깔끔한 동기화를 위한...] 간격으로 각 소켓에 대응되는 isZombiable과 같은 정수값을 증가 시켜 줍니다. 이 값이 소켓과 대응되는 현재 상태에서 최고값을[막 로그인했다면 보통 40, 플레잉 상태라면 보통 20...]넘어선 경우 해당 소켓은 strongly closed 상태가 된거죠. 따라서 그에 상응하는 일을 하시면 되겠습니다.
실제로 strongly closed socket에 대해서 비동기적으로 메시지를 보낼 경우 올바른 타이밍에 에러값을 얻어 내실수 없습니다..
동기적으로 할 경우엔 상당한 블럭 타임을 경험하실겁니다....
기본적으로
기본적으로 방법이 없습니다 -_-;
OS 의 TCP/IP 스텍 옵션에 keepalive가 켜져 있다면
아마 2시간후에 -_-; close 메세지를 받게 될것이고
그렇지 않다면 서버는 판단하지 못합니다
물론 keepalive 옵션의 시간을 조절할수도 있습니다
혹은 현재 접속해 있는 client들에게 타이머를 두고
패킷을 한번 보내보면, 몇십초 내에 -_-; 클라이언트가
접속이 끊어졌는지 판단할수 있게 됩니다
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
recv에서 timeout 체크를 하는것도 답이 되지 않을까요?
recv에서 timeout 체크를 하는것도 답이 되지 않을까요?
timeout 체크는
- setsockopt에서 SO_RCVTIMEO를 사용하거나
- select후에 recv해서 사용하는것도 방법이 될거 같습니다.
기본적으로 클라이언트와 쓰레드가 1:1 대응되지 않는 한그방법은
기본적으로 클라이언트와 쓰레드가 1:1 대응되지 않는 한
그방법은 불가능합니다
1:1로 하려면 사용자의 수가 많이 제약되는 단점이 있죠
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
단일 쓰래드에서 select()의 time out을 쓰면 되져.폴
단일 쓰래드에서 select()의 time out을 쓰면 되져.
폴링 보내구 카운트 해서 몇번동안 응답이 없다면 죽었네..
소켓 제거, 해당 자료 삭제
별로 가능할거 같지 않은 이야기 인데요100명중 10명이 위에 질
별로 가능할거 같지 않은 이야기 인데요
100명중 10명이 위에 질문하신분말씀의 네트워크가 끊여진 상태고
90명에게서 select에서 걸어둔 타임아웃 시간전에
보통 recv 이벤트가 발생한다고 봤을적에 실용성이있을지요?
그리고 타임아웃은 클라이언트가 끊였다고가정했을때니까
아마도 타임아웃시간은 적어도몇분이상은 될텐데
그동안 이벤트가 없을리도 없고요
설사 그게되더라도
어차피 패킷을 보내 확인하려면
각각의 유저마다 쓰레드를 뛰어서 패킷을 보내봐야 합니다
그렇지않고 응답이 지연되서 select의 다른 유저들의 이벤트를
못받는 경우를 없엘수 있겠죠
설사 select로 보내기담당 쓰레드를 만든다 치더라도
문제가많을거같다는 생각이 드네요
그걸 다 처리하려면
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
Re: 소켓 프로그램에서요...
close에는 두가지의 유형이 있습니다. graceful close, strongly close...
후자의 경우엔 close와 관련된 FIN Sync packet이 상대방에게 전달되지 않게 됩니다.
보통 이러한 close를 감지하기 위해서 서버사이드에서 쓰이는 기법은 time stamping입니다.
time stamping을 하는 루틴은 보통 일정 시간[보통 1초 혹은 select 루틴에서 루틴이 끝나고 난뒤에.. <-깔끔한 동기화를 위한...] 간격으로 각 소켓에 대응되는 isZombiable과 같은 정수값을 증가 시켜 줍니다. 이 값이 소켓과 대응되는 현재 상태에서 최고값을[막 로그인했다면 보통 40, 플레잉 상태라면 보통 20...]넘어선 경우 해당 소켓은 strongly closed 상태가 된거죠. 따라서 그에 상응하는 일을 하시면 되겠습니다.
실제로 strongly closed socket에 대해서 비동기적으로 메시지를 보낼 경우 올바른 타이밍에 에러값을 얻어 내실수 없습니다..
동기적으로 할 경우엔 상당한 블럭 타임을 경험하실겁니다....
그럼 전 이만..
참고로 KEEPALIVE Sync Packet은 일방적인 경우라서 강제로
참고로 KEEPALIVE Sync Packet은 일방적인 경우라서 강제로 끊긴 리모트 엔드 포인트에 대해서 별다른 효과를 얻을 수 있는것은 아닙니다.
아 그리고 당연히 메시지가 도착하는 경우에는 저 isZombiable을
아 그리고 당연히 메시지가 도착하는 경우에는 저 isZombiable을 0으로 셋팅하셔야 겠죠...
댓글 달기