select의 쓸 수 있는 상태란?

purewell의 이미지

Quote:
int select(int size, fd_set* read, fd_set* write, fd_set* except, struct timeval* tv);

select에서 보통 read 값만 가져다 쓰잖아요.
(ioctl로 접속이 끊겼는지 알 수 있으니까...)

그런데 write값은 어떤 때 세팅되나요? (메인질문)

클라이언트가 recv*함수를 호출했을 때 세팅되나요?
만일 클라이언트가 recv* 함수를 호출하지 않은 상태에서
서버에서 send* 함수를 호출하면 블로킹되나요?
클라이언트의 OS에서 일단 받아놓고 보지 않나요?

simpid의 이미지

purewell wrote:
Quote:
int select(int size, fd_set* read, fd_set* write, fd_set* except, struct timeval* tv);

select에서 보통 read 값만 가져다 쓰잖아요.
(ioctl로 접속이 끊겼는지 알 수 있으니까...)

그런데 write값은 어떤 때 세팅되나요? (메인질문)

클라이언트가 recv*함수를 호출했을 때 세팅되나요?
만일 클라이언트가 recv* 함수를 호출하지 않은 상태에서
서버에서 send* 함수를 호출하면 블로킹되나요?
클라이언트의 OS에서 일단 받아놓고 보지 않나요?

의미 그대로 보낼 수 있을때 셋팅됩니다.

님께서 든 예의 경우를 생각해 본다면..
클라이언트가 recv()를 하는 여부와 상관없이 서버측에서 send()를 할 수 있습니다.
서버측 소켓에 버퍼가 있기 때문인데... select를 해 보면 write가 가능한걸로 나타납니다. 물론 클라이언트가 못받고 있는데(recv를 안했던지.. 네트웍 속도가 늦던지) 계속 send를 한다면 버퍼가 차서 select에서 블록되게 됩니다.

mach의 이미지

TCP/IP에서 select를 쓴 경우로 가정하겠습니다.( 기타 파일IO제외)
송신자 => 커널 ========> 커널 ==> 수신자
................ 버퍼 .......com.......버퍼....................

위에서 보시는 바와같이 각 커널내부에 TCP/IP프로토콜 스택이 관리하는 버퍼(송수신 각 1개씩)가 있는데요. 이중 송신측의 커널내부의 송신 버퍼가 비워질때(1바이트라도 쓸수있을때), 송신측의 select에서 writable이 발생합니다.
그러나, 보통의 경우에 송신버퍼가 꽉차는 경우는 드물겠습니다.따라서, 별로 쓸일이 없는듯 보이기는 합니다만.

이를 정확히 테스트해보시려면 다음과 같은 상황을 연출해보시면 되겠습니다.
1. 송신측은 거대데이터를 매우빠르게 전송하고자 한다.
2. 통신라인(com.)은 데이터량에 비해 bandwidth가 낮다
3. 수신측은 송신측의 송신량을 미처 감당하기 어렵다.

위 1,2나 1,3의 가정으로 또는 1,2,3의 가정으로 코딩해보시면 되겠습니다.
위와 같은 상황이 연출될때, TCP/IP는 Flow control을 커널내부적으로 수행하는데,(즉, 양단간의 커널내부의 프로토콜스택끼리) 이 영향에 의해 send()가 불가능해질 수 있습니다.(1바이트도 쓸수없는 상황)

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

charsyam의 이미지

보통 WRITE는 기존에 write 시 실패했을 때, (현재 소켓 버퍼가 넘쳐서 더 이상 못보낼 때 ), 사용할 수 있게 됩니다. 이런 실패가 되다가, 소켓 버퍼가 비어서, 이제 write를 해도 보낼 수 있다라고 되면, WRITE 신호가 오게되죠. 이 때 보내면 됩니다. 그럼 고운 하루

=========================
CharSyam ^^ --- 고운 하루
=========================

cjy1126의 이미지

gets로 input입력을 받으면 wset 버퍼가 차게되서 select의 블럭이 풀리고, 상대가 data를 보내면 rset의 버퍼가 차게되어 select의 블럭이 풀리는 방식이였습니다.

댓글 달기

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