안녕하세요.. 서버와 클라이언트 통시하던중에 서버를 먼저 죽이고 , 다시 실행을 하면 "Address already in use" 이 메세지가 나오면서 서버가 실행이 안되는데여.. 바로 시작 할 수 있게 하는 방법 없나여.. 지금 setsockopt를 사용도해 봤는데 안되네여... netstat를 해보니깐 TIME_WAIT만 여러개 나오구여... 왜이런 현상이 일어날까요?
SO_REUSEADDR 옵션을 주면 됩니다.
int val = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof val) < 0) { perror("setsockopt"); close(sockfd); return -1; }
SO_REUSEADDR 옵션 설정을 해도 똑같습니다. 다른 방법은 없는지여?
if(setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt)) == -1) print_err(">>>>>>>>>>>>>>>>> setsockopt error");
서버하고 통신중 원치않는 상황에서 죽었을 경우, 해당 소켓은 열려진 상태로 마지막 패킷을 받아서 처리할때까지 TIME_WAIT에 걸립니다. 이렇게 받아진 것은 시스템에서 버리게 됩니다.
이 시간을 짧게 주시면 해당 문제는 해결이 됩니다. 시스템 파라메터를 바꾸셔야합니다. 바로 설정을 원하시면 /proc/sys/net/ipv4에 수치를 조작하시고나서, /etc/sysctl.conf에서 바꿔주시면 됩니다.
======================================== * The truth will set you free.
서버하고 통신중 원치않는 상황에서 죽었을 경우, 해당 소켓은 열려진 상태로 마지막 패킷을 받아서 처리할때까지 TIME_WAIT에 걸립니다.
어찌나 졸린지..~~
SO_REUSEADDR을 설정하면 대개는 되는데... 이상하네요.. 문제가 되는 소스코드를 함께 올리는 게 나을 거 같네요.
흠.. 그리고, .. SO_LINGER를 사용해 보세요. TIME_WAIT 상태에서 대기하는 시간을 줄일 수 있을 겁니다.
SO_LINGER * used to control whether and how long a call to close will wait for pending ACKS. * connection-oriented sockets only
리눅스에서 작업을 하신거죠?
제 예상컨데 이렇게 하면 SO_REUSEADDR을 하셔도 에러가 납니다.
1.socket create 2. bind and error 3. so, SO_REUSEADDR 처리 ==> 여전히 에러 발생.
이 순서를 이렇게 해 보십시요.
1. socket create 2. SO_REUSEADDR처리 3. bind 수행 ==> 아마 성공할 겁니다.
다른 플랫폼에서는 첫번째와 같이 순서가 중요하지 않은데
리눅스에서는 이상하게 에러가 나더군요.
저도 SO_REUSEADDR해도 에러가 난 경험이 있어서
말씀을 드립니다.
위의 상황이 아닐수도 있다는 생각이 들지만요...^^
좋은 하루 되십시요.
PS) 혹시 성공하시면 답변이나 원인이라도 남겨주시면
다른 사람들에게 도움이 될 듯 하네요.
고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.
Address already in use 오류가 자꾸 떠서 한참 삽질 중이었는데 순서 문제 였네요 ㅠㅠ
소스코드를 포함시켜야 정확한 도움을 받으실수 있을겁니다. 말로만 아무리 해봤자 소용없죠.
혹시 다른 프로그램이 그 포트 bind해서 점유하고 있는지도 확인하셨나요? LISTEN으로 된것만 조사하시면 됩니다.
$ netstat -anp
그냥 netstat만 하면 LISTEN은 안나올겁니다.
Written By the Black Knight of Destruction
그 에러메시지는 TIME_WAIT 걸렸거나 다른 프로그램이 그 포트 잡고 있거나 둘중 하나입니다.
텍스트 포맷에 대한 자세한 정보
<code>
<blockcode>
<apache>
<applescript>
<autoconf>
<awk>
<bash>
<c>
<cpp>
<css>
<diff>
<drupal5>
<drupal6>
<gdb>
<html>
<html5>
<java>
<javascript>
<ldif>
<lua>
<make>
<mysql>
<perl>
<perl6>
<php>
<pgsql>
<proftpd>
<python>
<reg>
<spec>
<ruby>
<foo>
[foo]
SOL_SOCKET
SO_REUSEADDR 옵션을 주면 됩니다.
SO_REUSEADDR옵션 설정...
SO_REUSEADDR 옵션 설정을 해도 똑같습니다.
다른 방법은 없는지여?
TIME_WAIT시간때문입니다.
서버하고 통신중 원치않는 상황에서 죽었을 경우, 해당 소켓은 열려진 상태로 마지막 패킷을 받아서 처리할때까지 TIME_WAIT에 걸립니다. 이렇게 받아진 것은 시스템에서 버리게 됩니다.
이 시간을 짧게 주시면 해당 문제는 해결이 됩니다. 시스템 파라메터를 바꾸셔야합니다. 바로 설정을 원하시면 /proc/sys/net/ipv4에 수치를 조작하시고나서, /etc/sysctl.conf에서 바꿔주시면 됩니다.
========================================
* The truth will set you free.
TIME_WAIT
원치않은 상황에서 죽었을 때 TIME_WAIT 상태로 빠지는 것은 아닌 걸로 알고 있습니다.
TCP 세션이 SYN_RCVD나 ESTABLISHED 상태에서 active_close를 시도한 경우에 TIME_WAIT 상태로 떨어지는 걸로 알고 있습니다.
어찌나 졸린지..~~
SO_LINGER
SO_REUSEADDR을 설정하면 대개는 되는데... 이상하네요..
문제가 되는 소스코드를 함께 올리는 게 나을 거 같네요.
흠.. 그리고, .. SO_LINGER를 사용해 보세요.
TIME_WAIT 상태에서 대기하는 시간을 줄일 수 있을 겁니다.
어찌나 졸린지..~~
socket reuse.
리눅스에서 작업을 하신거죠?
제 예상컨데 이렇게 하면 SO_REUSEADDR을 하셔도 에러가 납니다.
1.socket create
2. bind and error
3. so, SO_REUSEADDR 처리 ==> 여전히 에러 발생.
이 순서를 이렇게 해 보십시요.
1. socket create
2. SO_REUSEADDR처리
3. bind 수행 ==> 아마 성공할 겁니다.
다른 플랫폼에서는 첫번째와 같이 순서가 중요하지 않은데
리눅스에서는 이상하게 에러가 나더군요.
저도 SO_REUSEADDR해도 에러가 난 경험이 있어서
말씀을 드립니다.
위의 상황이 아닐수도 있다는 생각이 들지만요...^^
좋은 하루 되십시요.
PS) 혹시 성공하시면 답변이나 원인이라도 남겨주시면
다른 사람들에게 도움이 될 듯 하네요.
고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.
오오... 감사합니다. 바로 해결되었습니다
Address already in use 오류가 자꾸 떠서 한참 삽질 중이었는데 순서 문제 였네요 ㅠㅠ
역시 이런류의 질문에는..
소스코드를 포함시켜야 정확한 도움을 받으실수 있을겁니다.
말로만 아무리 해봤자 소용없죠.
혹시 다른
혹시 다른 프로그램이 그 포트 bind해서 점유하고 있는지도 확인하셨나요?
LISTEN으로 된것만 조사하시면 됩니다.
그냥 netstat만 하면 LISTEN은 안나올겁니다.
Written By the Black Knight of Destruction
Written By the Black Knight of Destruction
그 에러메시지는 TIME_WAIT 걸렸거나 다른
그 에러메시지는 TIME_WAIT 걸렸거나 다른 프로그램이 그 포트 잡고 있거나 둘중 하나입니다.
Written By the Black Knight of Destruction
댓글 달기