리눅스와 윈도우 간에 TCP 세션 종료 방식에 차이가 있나요??

morolty의 이미지

현재 상황은

서버 프로그램이 자바로 만들어져 있습니다..

리눅스에 서버 프로그램을 리눅스용 자바 머신을 이용해서 올려놨구요..

윈도우에도 똑같은 서버 프로그램을 윈도우용 자바 머신을 이용해서 올려놨습니다.

그리고 클라이언트 프로그램은 유닉스에서 동작하는 C 프로그램입니다..

.
.
.

그 와중에 세션종료에 관련된 문제가 발생했는데요,

서버프로그램이 죽었을때의 경우입니다.

.
.

윈도우 서버에 연결되어 있는 클라이언트 프로그램은 서버프로그램이 죽었을 경우, 정상적으로 세션이 끊깁니다.

리눅스 서버에 연결되어 있는 클라이언트 프로그램은 서버프로그램이 죽었을 경우, CLOSE_WAIT에서 무한정 대기합니다..

.
.

일단 클라이언트 프로그램 구조상 일방적으로 서버측으로 보내는 구조라

서버로 패킷을 보내보기 전에는 세션상태를 감지해낼 수 없어서 close()를 명시적으로 호출 할 수 없습니다..

당연히 그래서 CLOSE_WAIT에서 대기한다는건 이해하고 있습니다만...

.
.
.

여쭤보고 싶은 부분은,
윈도우에서 프로그램이 죽을때 세션종료 작업(?) - close 시그널을 보낸다든지..
리눅스에서 프로그램이 죽을때 세션종료 작업(?)이 서로 차이가 있는지에 대해서 궁금합니다..

.
.

이런 경우를 해결하신분이 계신다면 가르쳐주셨으면 정말 감사드리겠습니다..

※ close를 명시적으로 호출한다면 당연히 close_wait에서 대기하지 않는다는 사실은 알고 있지만, 전임자가 만들어놓은 프로그램 구조상 close() 호출시점을 정할 수 없고, 구조변경을 하기에는 시간이 너무 없다는점을 이해해주셨으면 합니다..

mirheekl의 이미지

큰 도움은 안 될지도 모르겠습니다만 그냥 몇가지..

- 서버 프로그램이 죽는게 정확히 뭘 의미하는지는 모르겠습니다만, 시그널이나 예외처리 핸들러를 통해 서버측에서 정상적으로 소켓을 닫을 기회를 제공할 수도 있습니다. 혹시 그 "죽는" 상황이 재현 가능하다면 그런 방법을 써보시면 어떨까 합니다.

- CLOSE_WAIT소켓이 클라이언트측에 남아있을텐데, 구글링을 좀 해보시면 그런 상태에 빠져있는 소켓들을 강제로 닫는 스크립트들이 좀 있습니다. 정 시간이 부족하다면 이런걸 주기적으로 돌려보면 어떨까 합니다. 또는, 프로그램 자체에 추가 스레드를 돌려서 내부적으로 비슷한 일을 하게 만들 수도 있겠죠.

- 시간이 부족하시다니 별 의미는 없겠지만.. 제 경우 저런 일을 방지하기 위해 아예 서버-클라이언트가 주기적으로 킵얼라이브 패킷을 주고 받게 만들었습니다.

--

morolty의 이미지

답변 감사드립니다.

일단 윈도우에서는 '서비스 종료' 로 서버를 죽이고, 리눅스에서는 kill -9으로 대몬을 죽입니다..

이 죽이는 방식에 있어서 뭔가 차이가 발생할 수 있을지도 모르겠다는 생각이 문득 드네요..

스크립트는 생각도 못했던 방법이군요..! 근본대책은 안되겠지만 말이죠..ㅜㅜ

추가 스레드를 돌린다는 의미는 스레드 생성후 해당 스레드 안에서 스크립트를 실행시킨다는 의미인가요?

아니라면 C 프로그램으로 혹시 CLOSE_WAIT등의 세션 상태를 알아내는 시스템 콜이 있을까요?

mirheekl의 이미지

서비스 종료는 정상적으로 프로그램을 종료하게 될 것이고, kill -9는 그렇지 않을 겁니다. (윈도에서도 taskkill /f 등으로 프로그램을 강제로 죽이면 비슷한 일이 발생할지 모르겠네요.)

따라서 kill로 죽이지 말고 유저 입력을 통해 데몬 스스로가 정상적으로 프로세스 종료를 하게 만들거나, kill -9가 아닌, 평범하게 핸들링이 가능한 다른 시그널을 준다든지 하는 방식으로 처리하시면 되겠네요.

다만 이렇게 한다 해도 서버 프로그램 오류 등으로 인해 비정상 종료될 가능성은 여전히 존재하니 이부분에 대한 예외처리나 시그널 처리도 신경써주시면 좋겠습니다.

프로세스 내에서 세션 상태를 알아보려면 주기적으로 서버에 데이터를 보내보면 되지 않을까 합니다.

--

morolty의 이미지

그냥 조금 더 시간을 들이더라도 세션 확인을 할 수 있는 구조로 변경하는게 옳을것 같네요....

달아주신 답변 참고해서 작업진행하겠습니다.

감사합니다 ^^

Lipi의 이미지

kill명령어로 종료하는 것보다 윈도우처럼 리눅스에서도 서버 프로그램에 종료하는 명령을 내릴 수 있게끔 만들어져 있을 것 같은데요.

그래도 만약 없다면, Linux머신에서 kill -15 PID 혹은 kill -SIGTERM PID 으로 종료하게 하면 어떤가요?

morolty의 이미지

프로세스를 종료시킬수 있는 모든 시그널로 테스트해봤는데 모두 같은 증상이네요^^;

일단은 쓰레드를 하나 돌려서 select이용해서 세션 writable이 90초간 없으면 일단 close호출하고 추후 패킷송신을 할때 새로운 세션을 맺도록 처리해서 해결은 했습니다..

패킷하나하나마다 세션 맺고 끊는 방식으로 해볼까 생각했는데 서버측이 버티기 힘들어 보이더군요..

bushi의 이미지

시그널 핸들러를 만들어서 close() 전에 shutdown() 하세요.

mirheekl의 이미지

핸들링이 불가능한 시그널도 있지만 어쨌든 외부에서 핸들링 가능한 시그널을 보내고 프로세스 내의 핸들러에서 포트 종료 처리를 하면 해결될겁니다.

--

댓글 달기

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