ESTABLISH 를 강제로 종료할수 없나요??

hatbary의 이미지

안녕하세요??

서버를 코딩하다가 답답한 상황을 만나서 질문 올립니다..

레드햇 8.0, 커널 2.4.18-14smp에서 작업하구 있는데요...

서버 소켓을 KEEPALIVE로 설정하지 않고, 타임아웃을 설정해놨구..
클라이언트 측에서는 KEEPALIVE로 설정하구, 마찬가지로 타임아웃 설정해놨구요..타임아웃은 30초 줬구요..

근데..가끔 어떤 상황이 발생하냐믄...

netstat로 보면 recv-Q와 send-Q가 모두 0인데, 상태는 ESTABLISHED로 되어있구, 서버 프로세스를 보면, read(소켓번호, .. 에서 블럭되어 있거든요..
그래서 프로세스는 SIGSTOP시그널을 받는거 같구, 그래서 멈춰있거든요..
좀비아닌 좀비..defunct나지도 않구, 프로세스는 버젓이 살아있구....아무런 동작도 안하구..그런 형태져..

이런 현상이 왜 생기는지, 이런 연결을 강제로 종료할수 있는지,(물론 프로세스 죽이지 않구요..lsof로 없앨수는 있겠지만..;;;), 이런 연결을 소스코드 차원에서, 감지하구 강제로 끊을수 있는 방법은 있을까요??

타임아웃을 걸었는데, 타임아웃이 먹히지 않는다는 건데..도통 모르겠네요..

그럼 답변에 미리 감사드리면서..구벅

서지훈의 이미지

타임아웃을 걸어놓은 부분의 소스를 올려 주세요...-_-ㅋ
전 그놈을 아주 잘 사용하고 있는데...
옵션을 줄 때 뭔가 문제가 있을 수도 있지 않을까 생각이 드네요...

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

추신-아무리 확실한 것도... 항상 의심하는 자세 아님...
밥벌어 먹기 힘듭니다...-_-ㅋ
'==' or '=' 의 압박... 죽음임...!!!

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

hatbary의 이미지

      if (soap->accept_timeout)
      { struct timeval timeout;
        fd_set fd;
        if (soap->accept_timeout > 0)
        { timeout.tv_sec = soap->accept_timeout;
          timeout.tv_usec = 0;
        }
        else
        { timeout.tv_sec = -soap->accept_timeout/1000000;
          timeout.tv_usec = -soap->accept_timeout%1000000;
        }
        FD_ZERO(&fd);
        FD_SET((SOAP_SOCKET)soap->master, &fd);
        for (;;)
        { int r = select((SOAP_SOCKET)(soap->master + 1), &fd, &fd, NULL, &timeout);
          if (r > 0)
            break;
          if (!r)
          { soap->errnum = 0;
            soap_set_receiver_error(soap, "Timeout", "TCP accept failed in soap_accept()", SOAP_TCP_ERROR);
            return -1;
          }
          if (soap_socket_errno != SOAP_EINTR)
          { soap->errnum = soap_socket_errno;
            soap_closesock(soap);
            soap_set_sender_error(soap, tcp_error(soap), "TCP accept failed in soap_accept()", SOAP_TCP_ERROR);
            return -1;
          }
        }

머..여기에 여러가지 soap이란 머시기가 마니 있는데, 이건 그냥 정의된 함수니깐 그냥 짐작하시는데로 동작하는거구, 여기 하구 나서 여러 설정을 거친다음에..

tcp accept를 합니다..이부분은 accept 타임아웃 부분이구.. 이다음은 recv할때와 send할때 타임 아웃 설정하는 부분인데..거의 똑같아요..

  if (soap_valid_socket(soap->socket))
  { for (;;)
    { 
#ifndef WITH_LEAN
      struct timeval timeout;
      fd_set fd;
      if (soap->recv_timeout)
      { if (soap->recv_timeout > 0)
        { timeout.tv_sec = soap->recv_timeout;
          timeout.tv_usec = 0;
        }
        else
        { timeout.tv_sec = -soap->recv_timeout/1000000;
          timeout.tv_usec = -soap->recv_timeout%1000000;
        }
        FD_ZERO(&fd);
        FD_SET((SOAP_SOCKET)soap->socket, &fd);
        for (;;)
        { r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
          if (r > 0)
            break;
          if (!r)
            return 0;
          if (soap_socket_errno != SOAP_EINTR)
          { soap->errnum = soap_socket_errno;
            return 0;
          }
        }
      }
.....
....
.....
 r = recv((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
        if (r > 0)
          return (size_t)r;
        if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
        { soap->errnum = soap_socket_errno;
....
....

send 부분은 recv부분과 똑같아서 올리지 않았습다..

추가적으로 클라이언트는 소켓옵션으로 SO_LINGER가 되어있슴다..

서지훈의 이미지

제가 좀 보니깐...
socket time-out 부분은 없는데요?
-_-ㅋ
걍... select() time-out 만 설정을 하신거 같은데...-_-ㅋ
이건 영 틀린 문제인데...
Stevens 아저씨 책 보세요...
setsockoption() 인가로 소켓 SND_TIMEOUT / RCV_TIMEOUT 설정하는게 있습니다...
이걸 해주셔야... 원하시는 데로 돌아가지 않나 생각을...-_-ㅋ

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

hatbary의 이미지

그렇다면...소켓 옵션으로 타임아웃을 설정한거하구 select에서 타임아웃 설정한거하고는 어떤 차이가 있나요? 전 같은건줄 알았는데..

다르다면 제 생각은 select의 경우 서버가 클라이언트와의 소켓을 만드는 시점에서 일정 시간내에 입력이나 출력이 없으면 리턴하는거 같구,,

소켓옵션으로 주면 소켓이 연결되어서 이리저리 데이터 왔다갔다 하는 동안에 어떤 잘못된 이유로 해서 클라이언트나 서버가 데이터를 일정시간 보내지 못한다면, 그때 타임아웃이 걸려서 소켓을 끊어버린다..

머 이런거 같은데..맞나요??

제가 생각이 짧아서리..;;

암튼 매번 답변 달아주시니 고맙네요..^^

서지훈의 이미지

select()는 쉽게 while() + sleep() 이렇게 생각을 하시면 됩니다...
그런데... socket 옵션 관련은...
직접 연결 되어 있는 socket에서 send / receive 를 원하는 소켓이 상대방에서 설정 시간 만큼 기다려도 반응이 없으면 접속을 끊도록 하는 것입니다.
이건 엄연히 전혀 다른 개념의 이야기 입니다...

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

hatbary의 이미지

허걱..그렇군요...

여태 그런것도 모르구..흠..

같은건줄 알구..왜 타임아웃이 안걸리나 고민했거든요..

그럼 소켓 옵션을 쓰게 되면, 만약 네트웍 단절이나, 아니면 클라이언트가 데이터 보내다가 끊는다거나 머..그러면 일정 시간 지나서 소켓을 닫는다는 이야기져?

아참..글구..진짜로 좀 아둔한 질문인데..소켓에 옵션을 여러개 둬도 각각의 옵션에 대한 동작은 어느정도 보장이 되나요??

예를 들어, 소켓옵션에 SO_REUSEADDR로도 주구, SO_LINGER로도 주구,,머..이런식으로 했을때요..

서지훈의 이미지

네...
제가 해본봐로는 아직 간섭은 없었던것 같네요...
제가 아직 모든 옵션을 사용해 본건 아니지만...
그러나... 어떤걸 사용하기 위해선 따른 필요한 옵션들은 있는듯 하구요...^^

저도 이거 또 분석 할려면 책 뒤져야...^^

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

hatbary의 이미지

흠..글쿤요..답변 감사함다..

아직 select를 통한 타임아웃과 소켓옵션을 통한 타임아웃에 대한 구분이 명확하진 않지만..헤헤

자꾸 질문해서 죄송하지만, 첨 질문에서 말한 recv-Q와 send-Q가 0이고 ESTABLISHED되어 있는 상태는 어떤 경우에 발생하는지..알려주시면..정말정말 고맙겠슴다..^^;;;
요놈들은 시간이 지나도 없어지지도 않구, 그냥 남아있거든요..그래서 프로세스를 read에서 블록시키는거 같아요..

서지훈의 이미지

제 생각엔... 이런 경우에도 일어나지 않을까 생각을 하는데요...
상대방의 프로그램의 이상이나 네트웍 이상등으로 통신 양단이 접속을 끊지 않고...
상대방의 socket에서 read()를 할 경우...
이런 경우에 흔히들 일어나지 않을까 생각을 합니다.
write()의 경우는 상대방의 프로세스가 죽그나 하면 바로 알아 채는데...
read() 에선 좀 문제가...

그리고 좀 더 자세한 상태에 관한 정보는 책을 참고를...
저도 이 부분은 완전히 개념이 잡혔다고 말씀을 드리기가 좀 뭐해서요...

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

hatbary의 이미지

넵!! 감솨함다^^

댓글 달기

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