일반적으로 모든 파일과 소켓은 기본값으로 블럭킹 모드를 사용하게 된다.
이는 1:1 통신이나 외부 개입이 없는 프로그램이라면 별로 문제가 없을 것이지만, 이러한 구조는 희박하다.
따라서 여러개의 소켓을 가지고 통신을 한다면 처리할 데이터가 없는 경우에는 recv 에서 바로 빠져 나와 다른 소켓을 처리할 수 있는
방식인 Non-Blocking 방식으로 변경 한다.
일반 파일일 경우만 처음부터 Non-Blocking 모드로 열 수 있으며, 소켓 같은 경우, fcntl () 함수를 이용해서 넌블록킹으로 전환해야 한다.
fcntl()에 F_GETFL 인수를 사용하면 기존 플래그 값을 읽어올 수 있다. 여기에 O_NONBLOCK 옵션 플래그를 OR 연산으로 더해주고
F_SETFL로 파일 기술자에 플래그를 적용하면 넌 블럭킹 모드로 전환된다.
예제 ) if ( fcntl(fd,F_SETFL,O_NONBLOCK | fcntl(fd,F_GETFL)) == -1 ) { ... error . .. }
Non - Blocking 모드에서 Connection
넌 블록킹 모드에서 connect 을 호출 하면 항상 -1 이 리턴 된다. 보통 connect 가 -1 ㅇ을 리턴 하면 실패를 의미하지만 넌 블럭킹의 경우
조금 다르다.
1. 연결이 진행중이지만 넌블럭킹이므로 바로 리턴된 경우로 errno가 EINPROGRESS로 설정된 경우이다.
그 뒤에, getsockopt 함수에서 SO_ERROR 옵션으로 연결상의 에러가 생겼는지 확인해본 뒤 사용하면 된다.
코드 상에서 명시적으로 리턴값을 확인하지 않음을 표시하여 불필요한 코드를 삽입 하지 않도록 유의한다.
예제 )
(void) connect(fd,ai_ret->ai_addr,ai_ret->ai_addrlen);
이후 셀레트 같은 함수를 이용해 쓰기 가능 상태인지 검사한다.
fd_set fdset_w;
FD_ZERO(&fdset_w);
FD_SET(fd,&fdset_w);
if(select(fd+1,NULL,&fdset_w,NULL,NULL) == -1) { .. error...}
쓰기 상태가 되면 select 함수는 리턴을 해주게 되는데 정상 리턴인지 에러인지 확인하기 위해 getsockopt에 SO_ERROR 옵션 지정한다.
넌 블럭킹 모드에서 recv 리턴값의 의미
양수 : 성공 - > 소켓 쉰 버퍼로부터 읽어들인 바이트 수
-1 : 읽을 데이터가 없음 - > Error가 EAGIN으로 설정됨
-1 : 에러 발생 : error 가 error 번호
넌 블럭킹 모드에서 send 리턴값의 의미
양수 : 성공 -> 소켓 송신 버퍼에 복사한 바이트 수
- 1 : 소켓 송신 버퍼의 공간 부족 ( error -> EAGIN )
- 1 : error
'C 프로젝트 > 리눅스 프로그래밍' 카테고리의 다른 글
Thread Safe (0) | 2014.05.23 |
---|---|
epoll (0) | 2014.05.22 |
C 라이브러리 - 패턴 매칭 사용 예제 (0) | 2014.04.04 |
C 라이브러리 - 패턴 매칭 (0) | 2014.04.04 |
조건 변수 , 뮤텍스 (0) | 2013.12.26 |