소켓 쓰기, 읽기 관련 의문점
@@ 쓰기의 경우 
1) 소켓을 블락(기본)으로 옵션을 주었을때.
소켓에 1만 바이트를 씁니다. 그 결과가 궁금합니다.
# 제가 예상 다음과 같은 경우의 수가 존재 하는 듯 하고요
a. 만 바이트를 쓸때까지 기다린다.  그리고 만의 값을 반환 한다.
b. 만 바이트를 쓰다가 쓰기 힘들면, 포기한다. 그리고 쓴 만큼의 양을 반환한다.
# 저는 a. 의 현상이 읽어날것 같습니다.
2) 소켓을 논블락으로 주었을때.
소켓에 1만 바이트를 씁니다. 그 결과가 궁금합니다.
# 제가 예상해보면 다음과 같습니다.
a. 커널 내부에 존재 하는 (sk_buff??)에 큐잉이 가능한 만큼 큐잉하고, 큐잉한 만큼을 반환합니다. (즉시)
- 큐잉이 가능한 것은 소켓(?)이 할당 할수있는 메모리 크기(?)라고 생각을 할수있을까요??
그 결과 내린 결론 ) write 함수를 while(1)에 길이가 다 보내질때까지 넣는 것은 논 블락일 경우에만 필요하다.
@@ 읽기의 경우 
1) 블락 소켓을 통해 읽을 때.
소켓을 통해 만 바이트를 읽습니다.
# 제가 예상해 보면 다음과 같습니다.
a. 만 바이트를 읽을때까지 기다리고 읽은후 만을 반환한다.
b. 만 바이트를 읽다가 읽기 힘들면 포기 하고 읽은 만큼의 수를 반환한다.
# 제 생각 a.
2) 논블락 소켓을 통해 읽을때.
소켓을 통해 만 바이트를 읽습니다.
# 제가 예상해 보면 다음과 같습니다.
a. 커널 내부에 존재 하는 sk_buff??를 통해 가능한 만큼 읽고,
읽은 만큼 의 수를 반환 한다.
결론 ) 쓸때와 마찬가지고 while()로 read를 감싸 주는 것은 논 블락일때만 
필수적이다.
궁금합니다.. 너무 질문이 방대 하죠? lol


소켓 쓰기, 읽기 관련 의문점
소켓을 블락(기본)으로 옵션을 주었을때.
소켓에 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번안해봤는데요. 윗분 말씀
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 이 플래그는 완전한 요구가 만족될때까지 작동을 블럭킹하도록 요구한다. 그러나, 만일 신호가 발생하고, 에러나 단절이 발생하거나 받은 다음 데이터가 전에 반환된 데이터와 다른 타입이라면 호출은 여전히 반환된다.rommance.net
댓글 달기