GNU C에서 recv() 시에 버퍼가 flush 되는지 궁금합니다.

morolty의 이미지

정말 별다른 코드는 없고

서버측에선

while(1){
     nrecv = recv();
     fprintf(stderr,"buff: [/%s], nrecv: [/%d]\n",buff, nrecv); ( %앞의 / 기호는 신경쓰지 말아주세요.. %s라고 쓰니 kldp에서 깨져서 임의로 넣었습니다..)
}

만 하고 있고

클라이언트 측에선connect() 후에

1. write() 한 두세번하다가
2. close() 없이 강제로 끊어지게 만듬

그 상황에서 서버에선 recv 해도 버퍼가 flush 되지 않는거 같습니다.
fprintf로 찍어보니 recv의 리턴값은 0인데, buff는 마지막으로 클라이언트로 받았던 패킷을 계속 가지고 있네요..
원래 recv가 버퍼 플러쉬 작업을 해주지 않는 건가요?

jick의 이미지

음, 코드가 깨진 것 같지만, recv나 read나 scanf나 기타 POSIX 혹은 C에서 기본적으로 제공하는 거의 모든 함수는 "버퍼 flush"를 해주지 않습니다.

즉 recv가 리턴 코드로 n을 돌려주면 버퍼의 첫 n 바이트만 유효합니다. (나머지 부분은 recv를 부르기 이전 상태로 유지될 것 같은데 이게 보장되는지는 잘 모르겠네요.)

morolty의 이미지

계속 수정해서 본문내용을 보기좋게 고쳐보려 했는데 잘 안되네요 읽기 힘들게 글 써서 죄송합니다...

예를들어 클라이언트로부터 wirte()로 "1234567890"을 보냈을 경우,

서버측에서 recv()를 2바이트씩 받아들이면
12
34
56
78
89
으로 받아들이는걸로 기억하고 있는데 그러면 이건

1. 12를 받고, 12를 지워서 34567890이 남음
2. 34를 받고, 34를 지워서 567890이 남음
.
.
.

이런식으로 되는게 아니고 버퍼의 index를 받아오거나 아니면 다른방식이 되는거였던가요..???

jick의 이미지

물론 커널이 내부적으로 버퍼를 가지고 있습니다만 그건 커널의 버퍼이지 유저 프로그램의 버퍼가 아니죠.

커널이 네트웍 카드로부터 패킷을 받는 시점과 유저 프로그램이 recv를 부르는 시점은 서로 동기화가 안되니까, 커널이 유저 스페이스의 영역을 버퍼로 쓸 수는 없습니다. (커널 입장에서 볼 때 유저 프로그램이 그 버퍼를 계속 쓸 거라는 보장도 없고.)

그러니까 서버가 recv를 만약 2바이트씩 받아서 버퍼 1234567890이 생겼다고 해도 이 버퍼는 커널 내부에 숨겨져서 커널만 볼 수 있는 영역이지 사용자 프로그램이 관여할 수 있는 영역이 아닙니다.

ymir의 이미지

recv 가 0 을 리턴했다면 peer 가 shutdown 되었다는 뜻이죠.
게다가 buff 에는 아무런 값도 세팅하지 않았을테니..
buff 의 값을 찍어봐야 recv 호출하기 전에 buff 에 남아 있던 값이 그대로 출력될 뿐입니다.
연결이 끊어졌는데 굳이 socket 을 갖고 뭘 해보려는 시도는 별 의미 없을것 같네요. 그냥 close 하시면 됩니다.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

댓글 달기

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