Non-Blocking 소켓 연결후 연결끊김(connection lost)을 알아내는 방법?

dorado2의 이미지

Non-blocking 모드로 서버에 연결하는 코드를 작성중입니다.
UnicastOpen(), UnicastRecv() 등과 같이 Wrapper 형태로 작성을 하고 있습니다.

UnicastOpen을 non-blocking 모드로 구현하면 대략 아래와 같은 절차가 됩니다.

non-blocking 모드 설정 -> connect() -> errno EINPROGRESS 체크
-> select() -> getsockopt () 체크

UnicastRecv()는 간단하게 아래와 같이 구현하려 합니다.

connection 상태 체크 -> select() -> recv()

즉, connection이 끊기지 않은 상태인지 UnicastRecv()에서 한 번 체크해야 하는 상태입니다.

그냥 뒤에 이어져서 나오는 recv()의 결과에 따라 처리할 수도 있겠지만, 사양상 UnicastRecv()
함수 역시 blocking이 되면 안 되기 때문에 별도의 쓰레드 상에서 구현하다 보니 recv()의 결과를 이용하기는 힘듭니다.

UnicastOpen() 함수에서는 connect의 리턴값과 errno, sockopt 값을 체크해서 connect 시도가 성공적인지
제대로 체크가 된다고 보구요.

UnicastOpen() 함수가 제대로 실행되었지만, UnicastRecv() 실행 이전에
connection이 끊기는 경우를 탐지해야 하는데, 이를 어떻게 할지가 조금 난감하네요.

구글 검색을 통해 getpeername()이나 read(fd, &ch, 0)를 사용해보았지만 제대로 동작하지 않습니다.
UnicastOpen() 실행 이후에 네트워크 cable을 뽑아놓았음에도 불구하고, 두 경우 모두 0을 return하는
걸 보니 connection이 끊긴 것을 알아차리지 못하는 모양입니다.

connect를 2번 해보는 것도 한 방법인 것 같은데, 이 방법이 유일하게 남은 것일까요?
좀 더 깔끔한 방법을 아시는 분 계시면 알려주시면 감사하겠습니다.

mirheekl의 이미지

일단 실제로 케이블을 뽑는것이라면 온라인 여부만 체크하는 것을 따로 돌리면 되겠지만 그것은 아니실테고
정상적으로 close하는것이 아닌, 통신주체가 다운되는등의 이유로 연결이 죽었을때를 감지하려는 것으로 이해했습니다.

근데 해보셔서 아시겠지만 이게 쉬운일이 아닙니다.
SO_KEEPALIVE_VALS를 이용할 수 있으나 이것도 연결종료를 그즉시 감지해낼수는 없으며 그나마도 모든 플랫폼에서 다 지원하는 것도 아니라고 알고있습니다.

결국 직접 킵얼라이브 패킷을 주고받아야 되는걸로 알고있는데요. 이렇게 되면 상대방이 다운되더라도 그 킵얼라이브 주기동안은 알아낼수가 없는거지요..

제가 문제를 제대로 이해했는지는 모르겠으나,
안전하게 하시려면 수동으로 데이터를 교환하는 방식으로 해결을 보심이 어떨까 합니다.
커넥션을 두 번 한다는게 어떤 의미인지는 모르나 하여튼 자동으로 해주는것은 없다 생각하고 말씀하신 류의 별도의 방법을 써보시는게 좋겠다는 얘기죠.

--
This is for you new people. I have just one rule :
Everyone fights, no one quits. If you don't do your job, I'll shoot you myself. Do you get me?

--

dorado2의 이미지

답변 감사드립니다.

사양서대로 구현을 하고 있는 중인데, "connection lost"인 상태에서 UnicastRecv() 함수를
호출하면, 따로 정의된 Error Code를 return해주어야 하거든요.

저는 케이블을 뽑아서 테스트했던 건데, server가 죽는 경우일 수도 있을 것 같고, 좀 애매하긴 하네요.
KEEPALIVE도 들어보긴 했는데, 주기를 설정하자니 한없이 작게 하기도 그렇고 명확한 솔루션이 될지 의문이 있네요.

답변 말씀 참조하도록 하겠습니다~

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.