소켓 쓰기, 읽기 관련 의문점

febace의 이미지

@@ 쓰기의 경우
1) 소켓을 블락(기본)으로 옵션을 주었을때.
소켓에 1만 바이트를 씁니다. 그 결과가 궁금합니다.
# 제가 예상 다음과 같은 경우의 수가 존재 하는 듯 하고요
a. 만 바이트를 쓸때까지 기다린다. 그리고 만의 값을 반환 한다.
b. 만 바이트를 쓰다가 쓰기 힘들면, 포기한다. 그리고 쓴 만큼의 양을 반환한다.
# 저는 a. 의 현상이 읽어날것 같습니다.

2) 소켓을 논블락으로 주었을때.
소켓에 1만 바이트를 씁니다. 그 결과가 궁금합니다.
# 제가 예상해보면 다음과 같습니다.
a. 커널 내부에 존재 하는 (sk_buff??)에 큐잉이 가능한 만큼 큐잉하고, 큐잉한 만큼을 반환합니다. (즉시)
- 큐잉이 가능한 것은 소켓(?)이 할당 할수있는 메모리 크기(?)라고 생각을 할수있을까요??

그 결과 내린 결론 ) write 함수를 while(1)에 길이가 다 보내질때까지 넣는 것은 논 블락일 경우에만 필요하다.

@@ 읽기의 경우
1) 블락 소켓을 통해 읽을 때.
소켓을 통해 만 바이트를 읽습니다.
# 제가 예상해 보면 다음과 같습니다.
a. 만 바이트를 읽을때까지 기다리고 읽은후 만을 반환한다.
b. 만 바이트를 읽다가 읽기 힘들면 포기 하고 읽은 만큼의 수를 반환한다.
# 제 생각 a.

2) 논블락 소켓을 통해 읽을때.
소켓을 통해 만 바이트를 읽습니다.
# 제가 예상해 보면 다음과 같습니다.
a. 커널 내부에 존재 하는 sk_buff??를 통해 가능한 만큼 읽고,
읽은 만큼 의 수를 반환 한다.

결론 ) 쓸때와 마찬가지고 while()로 read를 감싸 주는 것은 논 블락일때만
필수적이다.

궁금합니다.. 너무 질문이 방대 하죠? lol

kkuokk의 이미지

소켓을 블락(기본)으로 옵션을 주었을때.

소켓에 1만 바이트를 씁니다.

그 결과는

"CP send buffer의 여유 공간 만큼 복사하고

그 복사 된 사이즈를 리턴함."

그럼 소켓을 넌블락으로 옵션을 주었을때.

소켓에 1만 바이트를 씁니다.

그 결과는

"CP send buffer의 여유 공간 만큼 복사하고

그 복사 된 사이즈를 리턴함."

위의 결과로 블럭이든 넌 블럭이든 같은 결과가 나오는 것을 확인 할 수 있습니다.

그럼 어떤 경우에 차이가 날까요?

그 경우는 바로 TCP send buffer의 여유공간 (즉, 데이터를 복사 할 수 있는 공간)이 없을 경우 입니다.

블럭일 경우 여유 공간이 생길 때까지 블록 되어 있다가 여유 공간이 생기면 해당 데이터를 TCP send buffer에 복사하고 복사된 사이즈를 리턴합니다.
넌블럭일 경우에 -1을 리턴하며 errno 은 EWOULDBLOCK으로 셋팅합니다.

read(recv)의 경우도 위와 같습니다.

일반적인 경우에는 문제가 되지 않으며 읽을 것이 TCP recv buffer에 없을

경우 블럭 모드의 경우 읽을 것이 생길 때까지 기다리며 넌블럭의 경우 읽을 것이 없는 경우 -1을 리턴하며 errno을 EWOULDBLOCK으로 셋팅합니다.

입출력 함수 read, write, recv, send의 함수의 세번째 인자의 의미는 응용의 버퍼의 크기를 알려주는 인자일뿐 그것만큼 읽어오거나 쓰거나 하는 것에 대한 보장이 아닙니다.

^^ 신바람 꺽이왕자~~~~

송지석의 이미지

1번
a 해봤음. 계속 기다리더군요.
2번
안해봤는데요. 윗분 말씀에 의하면 c. 안되면 오류 리턴.
(man page 확인요망)

반환값
       보내진 문자의 수를 반환하거나 에러 발생시 -1을 반환한다.

에러
       이것은  소켓  레이어에 의해 발생되는 몇몇 표준적인 에러다.
       추가적인  에러는  기초  프로토콜   모듈로부터   발생되거나
       반환된다; 각각의 매뉴얼을 참조하라.

       EBADF  실제하지 않는 descriptor가 지정되었다.

       ENOTSOCK
              독립변수 s 가 소켓이 아니다.

       EFAULT 실제하지   않는   사용자   공간  주소가  매개변수로
              지정되었다.

       EMSGSIZE
              소켓이 메시지를 자동으로  보내줄  것을  요청했지만,
              보내진 메시지의 크기가 이것을 불가능하게 하였다.

       EAGAIN혹은 EWOULDBLOCK
              소켓이  non-blocking을  표시하였고,  요구된  opera-
              tion이 깨졌다.
       ENOBUFS
              네트웍  인터페이스를  위한  출력  큐가  가득  찼다.
              이것은 일반적으로 인터페이스가 전송을 멈추는 것으로
              나타난다.  하지만  이것은  순간적인   정체로   인한
              것이다.   (이것은 리눅스에서는 일어날 수 없다. 장치
              큐가 넘칠 때 패킷은 조용히 중단된다.)

3번
b
4번
안해봤는데요.. a로 예상.. (원래 recv의 일 자체가 읽을 수 있는 만큼 읽는 것임. fgets처럼 말이지요)
recv에 MSG_WAITALL 옵션을 켜면 받을 때 까지 기다립니다. 3번의 a처럼요.
      MSG_WAITALL
              이   플래그는  완전한  요구가  만족될때까지  작동을
              블럭킹하도록   요구한다.    그러나,   만일   신호가
              발생하고,   에러나   단절이  발생하거나  받은  다음
              데이터가  전에  반환된  데이터와  다른   타입이라면
              호출은 여전히 반환된다.

댓글 달기

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