SO_REUSEADDR의 경우 TCP상태에서는 안된다고 합니다.
UDP의 상태에서만 그 기능을 발휘한다고 하네요.
현재 소스를보면 socket (AF_INET, SOCK_STREAM, 0) 즉, TCP형태로
소켓을 생성시켜서 그렇습니다.
저 옵션을 사용하려면 socket (AF_INET, SOCK_DGRAM, 0)으로 해야할 것
같네요.
그에 관련된 문서는 아래를 참조해 보세요.
SO_REUSEADDR의 경우 TCP상태에서는 안된다고 합니다.
UDP의 상태에서만 그 기능을 발휘한다고 하네요.
현재 소스를보면 socket (AF_INET, SOCK_STREAM, 0) 즉, TCP형태로
소켓을 생성시켜서 그렇습니다.
저 옵션을 사용하려면 socket (AF_INET, SOCK_DGRAM, 0)으로 해야할 것
같네요.
그에 관련된 문서는 아래를 참조해 보세요.
TCP에서 SO_REUSEADDR 은 당연히 됩니다. time wait 에 대한 문제해결인데 보통 소켓 프로그래밍을 할때 습관적으로 넣어주는 옵션입니다.
자세한 내용은 Richard Stevens가 쓴 Unix Network Programming을 보시면 쉽게 이해하실수 있을겁니다
/***************************************************
* 가장 심플한 것이 가장 아름다운 것이다.
***************************************************/
The option is not supported by the proto
The option is not supported by the protocol.
즉, 프로토콜에서 지원하지 않는다는군요.
자세한건 man페이지를 이용하세요.
------------------------------
좋은 하루 되세요.
빠른 답변에 감사합니다.귀찮으시겠지만 보다 명확하게 말해 줄 수
빠른 답변에 감사합니다.
귀찮으시겠지만 보다 명확하게 말해 줄 수 없는지요...
단순히 서버/클라이언트 프로그램을 짜다가 bind() 에러 때문에,
찾은 해결책이 setsockopt()를 이용하는 것이라고 찾았습니다.
소켓 레벨을 뜻하는 SOL_SOCKET에서 SO_REUSEADDR를
지원하지 않는다는 건지요?
만약 그렇다면 어떻게 해야 해결을 할 수 있는건지요...
제가 사용했던 프로그램 소스는 다음과 같습니다.
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); }그 정도 소스로는 귀신 할애비가 와도 알 지 못합니다. 소켓을 만들때 어
그 정도 소스로는 귀신 할애비가 와도 알 지 못합니다. 소켓을 만들때 어떤 프로토콜을 명시해서 만들었는지, setsockopt를 호출하는 시점이 언제인지 정도는 파악할 수 있어야 합니다.
자주 오고가는 얘기지만, 좋은 (명확한) 답변을 위해서는 좋은 (명확한) 질문이 필요합니다.
네.. 제가 올바르게 질문을 못한 것 같습니다.전체 소스는 다음과
네.. 제가 올바르게 질문을 못한 것 같습니다.
전체 소스는 다음과 같습니다.
(결국 디버깅 하다가 제거 짠 소스가 되지 않고 웹에서 찾은 샘플 소스에
setsockopt()만 추가하였습니다)
int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */ struct sockaddr_in my_addr; /* my address information */ struct sockaddr_in their_addr; /* connector's address information */ int sin_size; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } int yes=1; // for setsockopt() SO_REUSEADDR, below // lose the pesky "address already in use"error message if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } my_addr.sin_family = AF_INET; /* host byte order */ my_addr.sin_port = htons(MYPORT); /* short, network byte order */ my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */ bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */ if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) \ == -1) { perror("bind"); exit(1); } if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } while(1) { /* main accept() loop */ sin_size = sizeof(struct sockaddr_in); if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, \ &sin_size)) == -1) { perror("accept"); continue; } printf("server: got connection from %s\n", \ inet_ntoa(their_addr.sin_addr)); if (!fork()) { /* this is the child process */ if (send(new_fd, "Hello, world!\n", 14, 0) == -1) perror("send"); close(new_fd); exit(0); } close(new_fd); /* parent doesn't need this */ while(waitpid(-1,NULL,WNOHANG) > 0); /* clean up child processes */ }사용하시는 OS 가 무엇인지가 필요한 시점이겠군요.
사용하시는 OS 가 무엇인지가 필요한 시점이겠군요.
OS : 레드햇 9.0Kernel Version : 2.3.20-30
OS : 레드햇 9.0
Kernel Version : 2.3.20-30-9 (레드햇에서 수정을 가한 것임)
GCC : 3.3.2
이렇게 됩니다.
SO_REUSEADDR의 경우 TCP상태에서는 안된다고 합니다.UDP
SO_REUSEADDR의 경우 TCP상태에서는 안된다고 합니다.
UDP의 상태에서만 그 기능을 발휘한다고 하네요.
현재 소스를보면 socket (AF_INET, SOCK_STREAM, 0) 즉, TCP형태로
소켓을 생성시켜서 그렇습니다.
저 옵션을 사용하려면 socket (AF_INET, SOCK_DGRAM, 0)으로 해야할 것
같네요.
그에 관련된 문서는 아래를 참조해 보세요.
http://pscal.skku.ac.kr/~angler/lecture/data_comm/data_comm_6th.ppt
------------------------------
좋은 하루 되세요.
[quote="codebank"]SO_REUSEADDR의 경우 TCP상태
거꾸로 아닌가요? UDP 일 경우 일반적으로 REUSEADDR 이 안되고 REUSEPORT 가 되는 걸로 알고 있습니다만... (멀티캐스트는 예외)
특별히 문제가 있어보이지는 않네요.
특별히 문제가 있어보이지는 않네요.
setsockopt 에서 문제가 생길거 같지는 않습니다.
다만 bind에서 맨뒤의 인자는 실제 sockaddr_* 구조체의 크기가 됩니다. 따라서 AF_INET 용으로 생성했으므로 sizeof(struct sockaddr_in) 이 되겠습니다.
그리고 버기님 말씀이 맞습니다. TCP의 경우에 연결지향이므로 서버가 죽더라도 클라이언트로부터의 쓰레기 패킷처리를 위해서 최대로는 2MSL시간동안 살아있습니다. 이것때문에 REUSEADDR을 사용하지 않으면 다시 listen port를 열수 없습니다.
========================================
* The truth will set you free.
[code:1] // lose the pesky "ad
// lose the pesky "address already in use"error message if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); }에서 &yes를 (void *)&yes로 하니깐 에러 없는데요...
집에나 갈까?
제가 알기론 아닌데여...
TCP에서 SO_REUSEADDR 은 당연히 됩니다. time wait 에 대한 문제해결인데 보통 소켓 프로그래밍을 할때 습관적으로 넣어주는 옵션입니다.
자세한 내용은 Richard Stevens가 쓴 Unix Network Programming을 보시면 쉽게 이해하실수 있을겁니다
/***************************************************
* 가장 심플한 것이 가장 아름다운 것이다.
***************************************************/
많은 답변에 감사합니다.하지만 문제를 해결할 수 있는 실마리는 조
많은 답변에 감사합니다.
하지만 문제를 해결할 수 있는 실마리는 조금 부족한것 같습니다.
혹시 OS의 설정 문제가 있는가라는 생각에 All 로 설치를 하고
커널에서 TCP 관련 미스무리 한 부분도 다 설정해서
프로그램을 테스트했지만 역시 묵묵 무답입니다.
혹시 컴파일 시 통신 옵션 레벨을 조절하는 뭐...
그런 것이 있는건 아닌지요?
저는 위의 소스로 문제없이 돼던데 혹시 include한 헤더파일목록을
저는 위의 소스로 문제없이 돼던데
혹시 include한 헤더파일목록을 볼수 있을까요?
집에나 갈까?
[code:1]#include <stdio.h>#inc
입니다.
앞의 코드에서 포트하고 backlog값 (void *)&yes
앞의 코드에서 포트하고 backlog값
(void *)&yes,,,,
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
요거랑 또 accept()후 내용만 조금 바꿨습니다.
저는 문제 없이 실해 돼구요...
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> int main(void) { int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */ struct sockaddr_in my_addr; /* my address information */ struct sockaddr_in their_addr; /* connector's address information */ int sin_size; int MYPORT = 9090; int yes; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } // lose the pesky "address already in use"error message if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } my_addr.sin_family = AF_INET; /* host byte order */ my_addr.sin_port = htons(MYPORT); /* short, network byte order */ my_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* auto-fill with my IP */ bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */ if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } if (listen(sockfd, 5) == -1) { perror("listen"); exit(1); } while(1) { /* main accept() loop */ sin_size = sizeof(struct sockaddr_in); if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept"); continue; } printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr)); { /// 이것 저것.... } close(new_fd); /* parent doesn't need this */ } close(sockfd); return 0; }집에나 갈까?
댓글 달기