소켓통신에서 블로킹 논블록킹에대해서..
간단하게 말하자면..
timeout = 10;
memset((char *)&srv_addr, 0x00, sizeof(srv_addr));
srv_addr.sin_family = PF_INET;
srv_addr.sin_addr.s_addr = inet_addr(host_addr);
srv_addr.sin_port = htons(tcp_port);
if ((li_sock_id = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
return (RET_ERR);
}
fcntl_flag = fcntl(li_sock_id, F_GETFL, 0);
if (fcntl_flag == -1) {
close(li_sock_id);
return (RET_ERR);
}
if (fcntl(li_sock_id, F_SETFL, fcntl_flag | O_NONBLOCK) == -1) {
close(li_sock_id);
return (RET_ERR);
}
rc = connect(li_sock_id, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
if (rc < 0 && errno != EINPROGRESS) {
close(li_sock_id);
return (RET_ERR);
}
FD_ZERO(&rset);
FD_SET(li_sock_id, &rset);
wset = rset;
tv.tv_sec = timeout;
tv.tv_usec = 0;
rc = select(li_sock_id + 1, &rset, &wset, NULL, &tv);
if (rc < 0) {
close(li_sock_id);
return (RET_ERR);
}
if (rc == 0) {
close(li_sock_id);
return (RET_ERR);
}
if (FD_ISSET(li_sock_id, &rset)) {
len = sizeof(error);
rc = getsockopt(li_sock_id, SOL_SOCKET, SO_ERROR, &error, &len);
if (rc < 0) {
close(li_sock_id);
return (RET_ERR);
}
}
if (fcntl(li_sock_id, F_SETFL, fcntl_flag) == -1) {
close(li_sock_id);
return (RET_ERR);
}
return li_sock_id;
}
여기서보면 마지막에 fcntl에서 다시 블록킹모드로 만드는거라고 하는데 이마지막에 쓰인 fcntl 함수에 대해서
잘이해가안갑니다.
만약에 fcntl함수가 없다면 connect 할경우에 상대방 서버가 네트웍이 죽어서 연결이 할수가 없을 경우에
connect 함수는 블럭상태에 빠지는거라고 들었습니다. 그렇다면 그 블록상태가 어느정도 시간이 걸리는지 알수는없나요?
논블록킹상태에서
connect 하고 바로 상대방 서버가 죽어있다면 에러를 리턴하고 select 에서 시간을 체크하여서 그 시간동안 연결이 되지 않는다면..
연결은 되지않고 자식프로세스가 죽는거겠죠?
결정적으로 궁금한건 왜다시 블록킹모드로 만들기위해 fcntl함수를 다시 썼나..
getsockopt 에서 SO_ERROR은 error변수에 에러번호를 출력하기위해서였나..
음..
우선 코드는
우선 코드는 코드블럭으로 싸주셔야 보기가 쉽습니다.
마지막에 쓴 getsockopt는, 소켓이 non-block이므로 에러가 생겨도 따로 얻어와야하기 때문입니다.
그리고 다시 block모드로 만든 이유는, 연결 이후에는 block모드로 소켓을 다루고 싶어서겠죠.
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
논블록이기때문에?
논블록이기때문에 에러를 따로얻어와야한다니요?
무슨말인지 이해가 잘안되네요 ㅠㅠ
테스트해본결과 연결이 잘됬을경우에는 getsockopt에러를 찍어보니 errno 를 안찍고 연결이잘안되서 EINPROGRESS이 에러를 떨어뜨릴경우에는
errno를 찍습니다 [111] 이란 에러입니다. 이경우는먼가요?ㅠ
안녕하세요
블럭함수의 경우,
블럭함수의 경우, 해당 작업이 끝나고나서 함수가 반환되기 때문에,
그 작업동안 어떤 일이 일어났는지 - 예를들어 읽기라면, 얼마나 읽어왔는지, 혹은 실패했는지를 반환값을 통해서 알 수있습니다.
하지만 non-block함수라면 당장 뭔가 못하는경우에 함수는 그냥 반환되고 실제 작업은 나중에 이루어지게 되겠죠. 따라서 잘 됐는지 안됐는지를 확인하는
추가작업이 필요하다는 의미입니다.
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net
댓글 달기