본문 바로가기

C 프로젝트/리눅스 프로그래밍

Socket Non-blocking



일반적으로 모든 파일과 소켓은 기본값으로 블럭킹 모드를 사용하게 된다.

이는 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