select에서 read처리는?

gnugpl의 이미지

select로 데이타를 read할시
2번 정도 client와 데이타를 주고 받은후
다음번에
select를 하지 않았음에도 불구하고 클라이언트에서 write가 성공합니다.

select에서 readable 상태를 체크한후, read함수를 호출해야
write가 성공하는것 아닌지요?

제가 잘못 테스트 한것인지? 아니면 커널 socket 버퍼사이즈가 여유가 있을때까지 지역버퍼에 그냥 write 된것이라
프로그램에서의 write는 성공하는것인지요?
궁금합니다.

mach의 이미지

gnugpl wrote:
select로 데이타를 read할시
2번 정도 client와 데이타를 주고 받은후
다음번에
select를 하지 않았음에도 불구하고 클라이언트에서 write가 성공합니다.

select에서 readable 상태를 체크한후, read함수를 호출해야
write가 성공하는것 아닌지요?

제가 잘못 테스트 한것인지? 아니면 커널 socket 버퍼사이즈가 여유가 있을때까지 지역버퍼에 그냥 write 된것이라
프로그램에서의 write는 성공하는것인지요?
궁금합니다.


TCP/IP 통신 관계되는 것을 정리하면 다음과 같습니다.
구성요소 : 송신응용프로그램, 송신측운영체제, 수신측운영체제, 수신응용프로그램
이렇게 4개가 관여하게 됩니다. 물론, 랜카드, 라우터등은 본 주제에서는 생략합니다.
1) 송신응용프로그램이 write()시
1-1) 송신응용프로그램이 write()를 호출하면, 송신측운영체제는 해당 응용프로그램의 소켓의 송신버퍼사이즈를 검사하고 수용가능하면 무조건 수용한다.
1-2) 송신측운영체제는 원격지 운영체제에게 송신을 개시한다. 원격지 수신측운영체제는 원격지 운영체제의 수신버퍼(원격지수신응용프로그램의 수신버퍼)가 허용하는 범위내에서 전부 수신한다.
*1-1~1-2까지에서 재전송등은 고려하지 않았습니다.이는 또다른 문제입니다.
* 여기까지가 송신입니다. 수신측 응용프로그램이 수신을 위한 read()를 호출하지 않아도 일단 수신측운영체제의 수신버퍼까지는 흘러가는게 정상입니다.
즉, 수신측응용프로그램이 수신명령을 수행하지 않아도 수신측운영체제까지는 데이터가 흘러가게 되는것입니다.
* 이때, 송신응용프로그램에서부터 원격지 수신운영체제까지를 담당하는것이 write()의 역할이라고 보시면됩니다. 일단 원격지 수신운영체제가 수신한다면, 이것은 신뢰성있게 송신되었다고 보기때문입니다.
* 님이 동기전송(synchronous communication)을 생각하셔서 이 문제가 생긴것같습니다. 님이 생각하는대로, write()하면 상대가 read()해야 다음이 진행된다고 생각하면(마치 전화처럼) 동기전송입니다. 이런 프로그래밍인터페이스도 있기는합니다. TCP/IP소켓은 아니고 Occam의 내부통신에서 구현한 랑데뷰메카니즘이 그러합니다. TCP/IP로 이를 구현하려면 조금 고생을 해야하지요. 아니면 이를 지원하는 tcp/ip위에 구현한 미들웨어를 사용하거나요.
* 다시 말하자면, TCP/IP는 내부적으로 비동기통신입니다.

부연하자면, write()는 원격지 운영체제까지 쓰는데 block()될 수 있고, read()는 지역수신버퍼에 데이터가 수신될때까지 block()될 수 있다라고 보면 됩니다.
select()는 read(), write()시 먼저 선검사를 수행하는 역할로 보면되겠지요.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

gnugpl의 이미지

일반적으로 수신 프로그램에서 read 함수를 호출할시 버퍼사이즈를 임이의 크기로 지정한후 수신합니다.
비동기 통신임에도 불구하고

송신측 프로그램단에서 한번에 write 한 바이트만
수신측에서 read 할수 있는 원리는 무엇인지요?

read 함수가 수신버퍼에서 '\0'까지 읽어들이나요?

아니면 제가 테스트한것이 우연이 일치인지요?

감사합니다.

RM -RF /bin

mach의 이미지

gnugpl wrote:
일반적으로 수신 프로그램에서 read 함수를 호출할시 버퍼사이즈를 임이의 크기로 지정한후 수신합니다.
비동기 통신임에도 불구하고

송신측 프로그램단에서 한번에 write 한 바이트만
수신측에서 read 할수 있는 원리는 무엇인지요?

read 함수가 수신버퍼에서 '\0'까지 읽어들이나요?

아니면 제가 테스트한것이 우연이 일치인지요?

감사합니다.

통신소켓상의 데이터흐름은 문자열이 아니라 바이너리데이터라고 보는게 맞습니다. 1바이트(\0)일지라도 그것은 분명한 데이터입니다. 사이즈를 보고 읽는것이 맞습니다. \0처럼 어떤 문자를 보고 읽지는 않습니다. 따라서, 통신프로그램의 저수준처리루틴에서는 string관련 함수를 호출하는것이 금기시됩니다. 이렇게 처리하면 외부공격에 아주 취약하기도 하기 때문입니다. 그래서 저수준처리에서는 보통 mem*() 호출들을 많이 사용합니다.

* 참고로 : 소위 제어문자라 할수 있는, Out of band data의 경우는 그 처리(보내기/받기방식)가 조금 차이가 납니다.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

댓글 달기

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