[질문] IOCTL 이후...
글쓴이: leolo / 작성시간: 토, 2005/01/15 - 4:30오후
IOCTL 함수를 이용해서 현재 네트워크 카드에 설정된 IP를 얻어오도록 하고, 이후에 UPD 소켓을 생성하고 소켓 번호를 보면 0이 됩니다.
그런데, 더 신기한 것은 0번으로 데이터가 전송되어 상대방에게 정확히 간다는 것입니다.
무엇이 문제인지..
IOCTL을 사용하는 것은 BBS에 있는 소스입니다.
..... static char ip[BUFFERSIZE]; int cmd = SIOCGIFCONF; max++; ifc.ifc_len = sizeof ifr; ifc.ifc_ifcu.ifcu_req = ifr; if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { return NULL; } if((s = ioctl(s, cmd, &ifc)) < 0) { close(s); return NULL; } nNumIFs = ifc.ifc_len/sizeof(struct ifreq); count = 0; strcpy( ip, localip ); for(i = 0; i < nNumIFs; i++) { struct in_addr addr; if(ifc.ifc_ifcu.ifcu_req[i].ifr_ifru.ifru_addr.sa_family != AF_INET) { continue; } addr = ((struct sockaddr_in *) & ifc.ifc_ifcu.ifcu_req[i].ifr_ifru.ifru_addr)->sin_addr; if(addr.s_addr == htonl( 0x7f000001)) { continue; } strcpy(ip, inet_ntoa(addr)); } close(s); return ip; }
소켓 생성 부분..
if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
return K_FAIL;
}
<--- 요기서 찍어보면 0이 됩니다...
아래와 같이 보내면 잘 갑니다..
if((si = sendto(sock, buf, sizeof(INFO_MESS_REQ), 0, (struct sockaddr *)&adr, sizeof(adr))) < 0)
{
....
}
Forums:
문제가 있는 코드지만, 운좋게 동작하는 것입니다.
소켓도 결국 file descriptor이기 때문에, socket() 함수를 실행할 경우 프로세스가 부여할 수 있는 가장 낮은 수를 sock 에 할당합니다.
일반적으로는 STDIN_FILENO(0), STDOUT_FILENO(1), STDERR_FILENO(2) 가 이미 할당되어 있으므로 3 이상의 수가 할당되겠지만,
여하간의 이유로 모든 file descriptor를 close()한 경우에는 0 부터 할당합니다.
따라서 socket() 함수 실행 직후 sock 변수의 값이 0 인 것은 비정상적인 경우가 아닐 수 있습니다.
그러나 인용한 BBS 코드의 경우는 문제가 있습니다.
소켓 번호를 저장하고 있는 s 변수의 값을 ioctl() 함수의 return value로 덮어쓰기 때문입니다.
다행히 ioctl() 함수의 return value가 0으로, s 변수의 원래 값과 동일하기 때문에 프로그램이 "돌아는" 가는 것이라고 생각됩니다.
너 행복하니?
그 코드를 올린 장본인으로서 사과드립니다. :)[code:1]
그 코드를 올린 장본인으로서 사과드립니다. :)
지금 잘 보니 저 s 는 ioctl의 리턴 값을 테스트 해보려고 값을 받았다가 그 값을 출력하는 printf는 지우고 s 에 대입하는 것만 남겨둔 코드 입니다. 대입문을 제거해야합니다. 그 코드를 그대로 사용하면 resource 낭비도 일어납니다.
2년만에 코드의 버그를 발견하다니.. 감사하군요.. ^^
---
http://coolengineer.com
댓글 달기