select의 쓸 수 있는 상태란?
글쓴이: purewell / 작성시간: 수, 2003/05/28 - 10:21오전
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에서 일단 받아놓고 보지 않나요?
Forums:
Re: select의 쓸 수 있는 상태란?
의미 그대로 보낼 수 있을때 셋팅됩니다.
님께서 든 예의 경우를 생각해 본다면..
클라이언트가 recv()를 하는 여부와 상관없이 서버측에서 send()를 할 수 있습니다.
서버측 소켓에 버퍼가 있기 때문인데... select를 해 보면 write가 가능한걸로 나타납니다. 물론 클라이언트가 못받고 있는데(recv를 안했던지.. 네트웍 속도가 늦던지) 계속 send를 한다면 버퍼가 차서 select에서 블록되게 됩니다.
TCP/IP에서 select를 쓴 경우로 가정하겠습니다.( 기타 파일IO
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. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
보통 WRITE는 기존에 write 시 실패했을 때, (현재 소켓 버퍼가
보통 WRITE는 기존에 write 시 실패했을 때, (현재 소켓 버퍼가 넘쳐서 더 이상 못보낼 때 ), 사용할 수 있게 됩니다. 이런 실패가 되다가, 소켓 버퍼가 비어서, 이제 write를 해도 보낼 수 있다라고 되면, WRITE 신호가 오게되죠. 이 때 보내면 됩니다. 그럼 고운 하루
=========================
CharSyam ^^ --- 고운 하루
=========================
채팅 프로그램짤때 사용해봤습니다.
gets로 input입력을 받으면 wset 버퍼가 차게되서 select의 블럭이 풀리고, 상대가 data를 보내면 rset의 버퍼가 차게되어 select의 블럭이 풀리는 방식이였습니다.
댓글 달기