네트워크 프로그램 문제 (CLOSE_WAIT) 해결 부탁

안상준의 이미지

네트워크 프로그램을 짜다가 CLOSE_WAIT가 생겨서 서버쪽의 host가 hang됩니다. CLOSE_WAIT를 해결할 수 있는 방법이 있나요?

발생하는 현상는
클라이언트와 서버가 통신을 하는 상태에서 갑자기 클라이언트의 Process를 강제로 종료를 시켰습니다. 그랬더니 서버쪽에서 CLOSE_WAIT가 생깁니다. 이렇게 여러번 클라이언트를 종료했더니 서버쪽에 CLOSE_WAIT로 인해 Hang됩니다.

서버쪽의 socket엔 KEEP_ALIVE를 설정했고, 클라이언트쪽에는 SO_LINGER 옵션을 주었습니다.

글을 찾아보니 CLOSE_WAIT는 주로 클라이언트가 갑자기 crash될때 생기는 거라고 하는데, CLOSE_WAIT를 없앨 수 있는 방법은 없나요.. 서버 프로세스를 restart하지 않고, 프로그래밍으로 해결할 수 있는 방법을 알려주시면 감사하겠습니다.

pynoos의 이미지

CLOSE_WAIT 인경우는 소켓이 상대방이 종료되었으므로,
이쪽에서도 종료해야한다는 의미입니다.

서버쪽이므로, 상대의 socket이 reset 되었다면,
(주로 recv 에서 -1 을 돌리는 것이겠지요.) 그 디스크립터를
close 해주면 되는 것입니다.

hang이 걸린다는 것은 다른 오류가 있기 때문인것 같은데요..?

안상준의 이미지

CLOSE_WAIT는 netstat -atn으로 보았을때 약 170개 정도가 있었습니다. 이 CLOSE_WAIT는 약 6시간정도 계속 보였습니다. 그 이후로는 그냥 서버 restart하였습니다. 서버쪽에서 CLOSE_WAIT가 생기면 Client쪽 (active close을 수행한 쪽)은 FIN_WAIT2 상태가 되는데, FIN_WAIT2는 fin_timeout으로 특정 시간이 되면 없어집니다. 그렇지만 서버쪽은 클라이언트의 crash인 경우는 무한하게 CLOSE_WAIT 상태가 되고, 이러한 state가 많으면 많을 수록 어느 한계치에 되면 서버쪽에서 tcp connect를 못받게 되고 hang이 됩니다.

이러한 경우엔 서버쪽에서 CLOSE_WAIT가 안 생기기게 하는 방법을 알고 싶습니다. 도움 부탁드립니다.

pynoos의 이미지

client 쪽 응답을 기다리는 쪽, 아마 select 나 recv 가 될텐데, 그 쪽에서 에러처리를 잘하고 있는데도,
CLOSE_WAIT 상태로 계속 있는건가요?

ahnhi의 이미지

안상준 wrote:
CLOSE_WAIT는 netstat -atn으로 보았을때 약 170개 정도가 있었습니다. 이 CLOSE_WAIT는 약 6시간정도 계속 보였습니다. 그 이후로는 그냥 서버 restart하였습니다. 서버쪽에서 CLOSE_WAIT가 생기면 Client쪽 (active close을 수행한 쪽)은 FIN_WAIT2 상태가 되는데, FIN_WAIT2는 fin_timeout으로 특정 시간이 되면 없어집니다. 그렇지만 서버쪽은 클라이언트의 crash인 경우는 무한하게 CLOSE_WAIT 상태가 되고, 이러한 state가 많으면 많을 수록 어느 한계치에 되면 서버쪽에서 tcp connect를 못받게 되고 hang이 됩니다.

이러한 경우엔 서버쪽에서 CLOSE_WAIT가 안 생기기게 하는 방법을 알고 싶습니다. 도움 부탁드립니다.

일반적으로 close() 함수를 사용할 경우 TCP 종료 패킷이 모두 송수신 된 다음에 프로그램이 종료되지 않습니다.!!
이를 위해 shutdown 함수 및 recv() 함수를 사용하여 네개의 패킷이 모두
송수신 되는 것을 확인하는 것이 좋습니다.

위에서 CLOSE_WAIT 상태라는 것은 recv FIN / send ACK 상태인데
서버측에서 이를 제대로 처리해 주지 못하는 것입니다.

1. trace를 통하여 프로세스가 블럭킹 상태로 빠지는지 확인.
2. tcpdump를 통해 종료 패킷이 모두 보이는지 확인.
3. 클라이언트에서 종료를 close()를 사용하지 말고 shutdown 사용
4. kill 시그널 시 TCP 종료 부분 추가

특히 클라이언트 종료시 발생하는 문제라고 했는데
이경우 TCP 종료 패킷을 모두 송수신 한 후 프로세스가 종료되야 하는데
그렇지 못해서 발생하는 문제인것 같습니다.

Effective TCP/IP Programming, Jon C. Snader, Wesley
위의 책을 보시면 TCP 종료에 관련된 내용이 있습니다.
괜찮은 책이니 한번 사서 보심이 좋을것 같습니다. :-)

不狂不及

jemiro의 이미지

위에 분들 말씀대로, 서버쪽 코드에서 예외처리를 해주면 해결 됩니다.
SIGPIPE 받아서 close 해줄수 있는 코드면 그렇게 해주어도 될듯하고,
아니면 socket api의 리턴값을 체크해서 close를 해주는 코드가 들어 가 있는지
확인해보세요.

댓글 달기

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