서버측에서 클라이언트가 죽었는지 체크하는 방법?

kkchlove의 이미지

http://125.179.204.32/ChattingServer.cpp

소스는 위에처럼 구현했습니다.

문제는 클라이언트쪽에서 갑자기 컴퓨터를 끊다던가 하는 행동을 취할 경우 서버는 연결이 끊어진거라고

인식하지 못합니다. 즉 send()함수 호출시 에러를 리턴하지 않습니다.

어떻게해야할까요? 아 공부하다보니 정말 답답한게 많네요^^;

하지만 재미는 잇내요... 메신저 주소 kkchlove@nate.com(네이트온), kkchlove44@hotmail.com

고수님들의 의견을 듣고 싶습니다. 메신저로 연락 주셔도 됩니다.

익명사용자의 이미지

주기적으로 ping을 날려서
일정 시간동안 답변이 없으면
에러난 접속으로 보고
끊어 버리는 방법을 보통 씁니다~

kkchlove의 이미지

그럴수 없나요?

dormael의 이미지

일반적으로 C/S의 핑은 ICMP를 이용하는게 아닌 자체 프로토콜(TCP나 UDP이용)에서의 특정 프로토콜을 의미합니다.

의미가 ping명령어가 수행하는것과 비슷할 뿐입니다.

대강 플로우를 생각해 보면,

수신시 SO_TIMEOUT값을 기반으로

1 - 1. 타임아웃 발생시 마지막으로 정상수신한 시간과 비교후 일정 시간이 넘었으면 세션 종료.
1 - 2. 정상패킷이 수신되었을 경우 마지막 정상수신 시간을 세션에 기록.
1 - 3. 잘못된 패킷이라고 판단될 경우 알아서 처리(그때그때 달라요.)

송신시에는 보통 바로 세션을 종료하거나 그냥 놔두거나 할것 같습니다.
위에서 패킷은 TCP나 UDP의 패킷이 아닌 자체 프로토콜의 패킷으로 보시면 됩니다.

-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.

seank76의 이미지

dormael님이 말씀하시는 케이스는 클라이언트가 정기적으로 데이타를 서버로 송신하는 경우만 해당되겠죠.

클라이언트가 비정상적으로 죽어버린 상황에선 서버에선 절대로 알수 없습니다. (이 경우엔 timeout이고 뭐고 다 쓸데없죠.)

유일하게 가능한 방법은 클라이언트로 데이타를 보내는건데 (TCP 자체 프로토콜로 ack가 돌아오지 않으니 socket이 닫혀버리겠죠.), 이 방법도 write()를 두번 해봐야 socket의 상태를 알수 있죠. (첫번째 write()가 socket을 닫아버리면 두번째 write()에서 error를 리턴합니다.)

전 게을러서 그냥 write(fd, (void *)"", 0) 이런 식으로 상태 체크하곤 하는데요, 제대로 하려면 정상적인 write()후에 클라이언트가 ACK 메세지를 리턴하는 방법이 좀 더 확실한것같습니다.

제가 잘못 알고 있을수도 있으니 혹시 다른 방법 아시는분, 가르침 부탁드립니다.

only2sea의 이미지

제가 보기엔 dormael님께서 하신 말씀으로 비정상종료된 클라이언트를 알 수 있을 것 같은데요. 대신에 좀 과장해서 클라이언트가 엄청 느리거나 네트워크가 매우 느려서 TIMEOUT을 넘어버리는 어이없는 경우가 생기면 접속이 끊어지겠지요.

예전에 온라인 게임을 할 때 다른 맵으로 이동할 때 클라이언트가 맵을 로딩하는데, 맵 로딩 중에 서버측의 패킷에 응답하지 않게 프로그램이 되어 있어서(즉, 소켓을 안 읽어서) 맵 로딩이 길면 접속이 끊어지곤 했습니다. 그래서 타임아웃 시간을 10초 더 늘려달라고 고객 지원 페이지에 제안을 했는데, 안 해 주더군요.

이제는 서명에 무엇을 써야하는지 생각해보자.

seank76의 이미지

TCP에서 timeout이라는게, 서버에서 각 socket마다 무슨 타이머를 돌리는게 아니고요, 클라이언트가 keep_alive 메세지를 보내야되요.

그래서 클라이언트 머신이 아예 다운된경우나 네트워크 케이블이 빠져버린 경우엔 서버는 그냥 마냥~ 기다리게 되는거죠.

only2sea의 이미지

아.. 그렇군요. 무슨 뜻인지 알겠습니다. TCP에서 알아서 해 주는 timeout을 의미하는 게 아니라 UDP에서 돌린다고 생각하면 말이 조금 되기는 하지요. 대신에 현재 접속된 클라이언트 수대로 서버에서 일일이 테이블 엔트리를 관리하고 한번씩 핑을 보내본다는 것은 마음에 안 드네요. 흠... 정말 님 말씀대로 알기 어렵네요.

이제는 서명에 무엇을 써야하는지 생각해보자.

kkchlove의 이미지

따로 스레드를 돌려서 udp소켓을 돌려서 확인할려고요.

그런데... 소켓이 활당되어 있다면 그 소켓 파일 드스크립트를 이용해 클라이언트 아이피 주소를 알아낼 수 있지 않아요?

그 함수 이름이 머에요?

park7275의 이미지

클라이언트를 수정할수도 있다면

클라이언트가 서버에게 heart bit 를 보내게 하세요

보내는 메시지가 있을경우는 쉴수 있게 하고

보낼것이 없을 경우 주기적으로 보내면

서버 쪽에서 처리가 쉬울듯하네요.

[KILL] 죽을각오로.........

[KILL] 죽을각오로.........

익명사용자의 이미지

핫빗에 한표 입니다.

kkchlove의 이미지

무엇을 말씀하시는건지 잘 모르겠습니다.

seank76의 이미지

Heart Beat, 즉 심장 고동소리란 얘기죠.
클라이언트가 서버한테 "나 살아있어!"라고 몇초(보통 5~10초)에 한번씩 최소한의 데이터를 보내는겁니다.

그런데 전 권하고싶지 않네요.
이미 TCP자체가 핫빗을 구현하는데 그 위에다 따로 할필요는 없다고 봅니다. (뭐 클라이언트의 생존을 바로 알아야되는 특별한 상황이 아닌 이상에요.)

그냥 ACK로 가시는게 훨씬 더 효율적일거에요.
서버가 데이타를 보낼때마다 클라이언트가 받았다는 답장을 보내는거죠.

답장않오면 소켓 끊어버리면 되고요.

근데 write() 두번 쓰는건 해보셨나요?

kkchlove의 이미지

클라이언트 쪽에서 쓰레드 하나 생성하여 거기에 UDP 에코 서버를 구현하여 패킷이 들어오면 바로 답을 하는식으로 구현하려고요.

서버쪽에서는 마찬가지로 쓰레드 하나 생성해서 30분에 한번씩 클라이언트들을 확인하려고 합니다. UDP 패킷을 하나 보내고 2초동안 오는 패킷이 없다면, 그 클라이언트는 죽은걸로 간주하게 하려고요...

그런데 코딩하다보니 에러가 나서 아주 지금 에먹고 있습니다. seank76님 메신저 없으신가요?

kkchlove의 이미지

안되던데요. 첫번째는 0바이트 전송해서 0바이트 리턴되고요. 2번째는 256인가?
하여간 그정도 되더라구요... ㅜㅜ 몇일째...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.