소켓에 있는 데이터를 비우려면?

하하의 이미지

소켓에 만에 하나 데이터가 남아 있어 비우려면 어떻게 해야 하나여?

fflush() 같은 함수는 없나요?

faye의 이미지

ioctl 명령어중에 FIONREAD이 있습니다. buffer에 있는 데이터

크기를 알아내는 것이죠..

크기를 알아내서 크기만큼 read하면 버퍼가 비워질 것입니다.

QnA에서 ioctl, FIONREAD 로 검색해보세요..

도움 되셨길.

익명 사용자의 이미지

음..... 위 함수 사용해 봤습니다.

nread 값은 0 이 떨어졌습니다.

헌데...

제가 게시물을 읽다 보니.. 이건.. read buffer 에 대한 내용인거 같더라구요..

;;;;;

send buf 에 대한.... 보낼 내용물이.. 있다면.. 비우고 싶습니다...

만약 상대쪽이.. 랜섭이 뽑혀.. 서버가.. send buf 의 내용을 보냈지만..

ack를 못받아.. 계속 send buf의 내용을 유지 하고 있을때...

해당.. sock 을 닫는 다면..

해당 연결이 안닫힘니다..................'

close 하기전.. send buf의 내용이 있다면.. 다 비우고 소켓을 닫고 싶습니다.

방법 좀 알려주세요 ^^;;;

익명 사용자의 이미지

제 질문에 밑으로 처질거 같아 다시 답 올립니다..

고수님들 답변좀....

꾀 오래 골머리 앓고 있는 문제라.. ㅋ

rasungboy의 이미지

send buffer 에 데이타가 남아있는경우

소켓을 닫을때 안닫힌다는 것은 혹 LINGER 가 설정되어

있어 그런게 아닐까 합니다.

LINGER 를 끄고 소켓을 닫아보세요.

익명 사용자의 이미지

/*
    mLinger.l_onoff = 0;
    mLinger.l_linger = 0;

    mLinger.l_onoff = 1;
    mLinger.l_linger = 30;

     등등 ....
*/
    if(setsockopt(mServerSocket, SOL_SOCKET, SO_LINGER, (char*)&mLinger,sizeof(mLinger)) < 0)
    {
        printf("%s %d: setsockopt(): %s\n", __FILE__, __LINE__, strerror(errno));

        return -1;
    }

링거 옵션... 해봤습니다..... 책도 보고..

실제로 값도 변경해 가며.... 일일히 테스트 했는데.. 위 문제의 답은 아니더군요...... ㅋ

익명 사용자의 이미지

그리고...

close(sockfd);

는 정상 리턴됩니다...

허나... netstat 해보면... establish 되있죠 ㅋ

rasungboy의 이미지

Anonymous wrote:
그리고...

close(sockfd);

는 정상 리턴됩니다...

허나... netstat 해보면... establish 되있죠 ㅋ

원래 소켓을 닫아도 establish 상태를 유지하느걸로 알고있는데
요....

익명 사용자의 이미지

예... 그렇다면...

위에 establish 는 ... 더 이상 생각 하지 않겠습니다...

다시.. 원점으로.. send buffer 에 남아 있는 데이터를.. 비우려면..

어떻게 해야할까요?

......

상대가.. 랜선이 뽑혀 데이터를.. 받을수 없는 상황입니다...

그렇다면.. send buffer 에는.. 여전히.. 데이터가. 있어.. 보내려고 합니다....

tcpdump 확인. 했습니다..

꼭좀.. 비우고 싶습니다. 헐헐

rasungboy의 이미지

Quote:

그렇다면.. send buffer 에는.. 여전히.. 데이터가. 있어.. 보내려고 합니다....

제가 알기로는 close 를 호출하는 순간 링거가 켜져있지 않으면

경직된 close(hard close) 를 하는것으로 알고 있습니다.

즉 send buffer 에 데이타를 보낼려고 하지 않고 리소스를 해제하며

핸들을 반환하는 것이지요.

혹 send buffer 에 데이타가 들어있어 보낼려고 한다는 것이

사실 그 데이타는 유효하지 않은 데이타며 (close를 호출해서 리소스를 반환

했으므로) 사실 보낼려고 하는것처럼 보이는 것이지 실상은 보내지 않는게

아닐까 합니다.

어떤점이 문제가 되어 이런 고민을 하시는건지 궁금하네요.. ^^;

익명 사용자의 이미지

흠.....

아뇨....

저도 그런줄 알았습니다.

단정지어서 말하는 이유는....

tcpdump | grep port

를 했을때...

분명.. 해당 연결이 끊어졌음에도 불구 하고..

계속.. 서버(응용 프로세스 말고 커널이라 하죠 ^^)가..

해당 클라이언트로.. 데이터를.. 보냅니다.....

당연 클라이언트는. 랜섭이 뽑혔으므로 ack를 못보내구요...

그럼 서번.. 계속.~~~ 보냅니다.

익명 사용자의 이미지

음..

머.. 위 문제야 어찌 됬던 상관없습니다..

헌데.. 정말 문제는..

poll() 함수에서.. 발생합니다.

예를 들어..

클라이언트와 서버간 연결은.. 주로 클라이언트에서..

소켓을 닫음으로서..

서번 해당 소켓을 정리합니다.

이말은..

클라이언트가 close를 하면 서번 poll 에서 하나의 이벤트를 감지하여

read 호출씨.. 0을 반환하므로서.. 클라이언트가.. FIN을 보냈다고 감지하고

서버의 할당된 fd 를 반환 하는 절차를 가지고 있습니다.

헌데...

tcp 특성상.. 상태가.. FIN 이나 기타 여타 데이터를 받지 못할 경우 (랜섭이

뽑혔을 경우가 대표적) 연결이 끊겼는지 알수 있는 방법이 없습니다..

이때 대부분의 서번.. polling 을 통해 주기적으로 클라이언트의 연결이 이상

없나를.. 물어봅니다...

만약 문제가 있다면...

해당 socket을 close 하죠........

여기까진 아무 문제가 없습니다.

문제는.. 위와 같이 socket을 끊고 난 후 조금 있다 다른 유저가 다시

서버에 connect 했을때......

서번 accept 후... 바로.. tj

rasungboy의 이미지

Quote:

분명.. 해당 연결이 끊어졌음에도 불구 하고..

계속.. 서버(응용 프로세스 말고 커널이라 하죠 ^^)가..

해당 클라이언트로.. 데이터를.. 보냅니다.....

당연 클라이언트는. 랜섭이 뽑혔으므로 ack를 못보내구요...

그럼 서번.. 계속.~~~ 보냅니다.

예 정상인것 같습니다.

연결은 끊어졌어도(핸들을 닫앗어도) 사실상 바로 연결이 끊긴것

을 바로 알지 못합니다. 그래서 close 를 해도 상태를 보면

established 상태가 되 있는것이지요. 아마도 이에 관련된것

같은데..

그래서 랜선이 뽑혓거나 하는 상황에 대해 연결이 바로 종료됐

는지 알지 못하는 상황 때문에 클라/서버 끼리 heartbeat

시그널을 보내 일정시간안에 응답이 안오면 연길이 끊긴걸로

간주하여 소켓을 닫는 방법이 널리 쓰이고 있습니다.

익명 사용자의 이미지

poll() 이 잘못된 데이터를.. 감지 합니다..

ㅠㅠ;;;;

위에 주저리 주저리 많이 썼습니다.

정확한 상황을 설명하지 못한거 같습니다.

여하튼....

전.. 이문제를 해결해야 하는데..

지금 그 문제의 원인으로 send buf에 데이터가 남아서 그렇다고

생각하고 있습니다..

..... 절 도와 주실분 안계신가요?

헐헐

rasungboy의 이미지

좀 비슷한 현상이 있었습니다..

poll() 써보진 않앗으나 저 같은경우 select 의

첫번재 인자인 max_fds 값을 설정하는 부분이였는데..

이 값을 잘못 셋팅하여 접속끊김이 감지 되지 않는

현상이 있어 고생했습니다.

poll() 도 select 와 비슷한 원리로 돌아갈거라 생각하는데

한번 이부분을 체크해보시는게 어떠실지 모르겠습니다.

별로 도움이 되지 못해서 이거 ^^;;

jenix21의 이미지

ap에서 send buffer 를 비울수 있는 방법은 없는 걸로 알고 있습니다.

if only..

익명 사용자의 이미지

응용수준에서 alive check를 하도록 서버를 만드세요.
타임아웃내에 클라이언가 액션을 취하지 않으면, 클라이언트에 대해 서버가 연결종료함(링거옵션 적절히 세팅하여, timewait상태로 빠지는 시간 최소화)

1. 모든 클라이언트에 대해 ping을 시도하여 검사.
2. 응용 프로토콜 수준에서 liveness검사

1또는 2와 타임아웃을 병행

* 1또는2는 일종의 heart beat 메카니즘이겠지요.

익명 사용자의 이미지

위는 클라이언트는 질문하신 분이 손댈수없는 경우도 가정했습니다.

익명 사용자의 이미지

위 손님은 잘 못 답변을 하신듯...

익명 사용자의 이미지

Anonymous wrote:
위 손님은 잘 못 답변을 하신듯...

글쎄요?
맞는 답변같은데요?
익명 사용자의 이미지

질문은..

서버가 ping을 시도하여 액션을 취하지 않았을 경우..

서버가 해당 소켓을 끊었을때 발생하는 문제에 대해 질문하고 있네요...

조건으로 해당 클라이언트는 접속후 랜선이 뽑힌 상태입니다.

;;;;;;

위 답변은 질문을 제대로 안 읽고 답해 주셨네요

june의 이미지

현재 통신이 끝난후에도 연결이 계속 되어있어서 그러신거죠?
원래 그래요. TIME-WAIT 라는걸로 검색해보세요.
그리고, TIME-WAIT를 없애는 방법은..
SO_REUSEADDR 옵션을 사용해보세요. 이것도 검색하시면 쭉 나올듯.

커피는 블랙이나 설탕만..

댓글 달기

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