2014-12-04 15 views
6

특정 IPv4 주소와 서버 포트 X에서 수신 대기하는 1 개의 IPv4 소켓 소켓과 특정 IPv6 주소와 동일한 서버 포트 X에서 수신 대기하는 IPv6 소켓이 필요한 서버 구현이 있습니다. IPv4 및 IPv6 주소는 동일한 인터페이스에 있습니다.IPv6 바인드 실패

나는 evconnlistener_new_bind를 사용하여 ipv4 소켓을 만들고 바인딩합니다. IPv6 수신기의 경우 코드는 다음과 같습니다.

memset(&sin6, 0, sizeof(sin6)); 
    sin6.sin6_family  = AF_INET6; 
    memcpy(sin6.sin6_addr.s6_addr, v6addr_bytes, IPV6_ADDR_LEN); 
    sin6.sin6_port  = htons(tcp_port); 

    fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); 
    evutil_make_socket_nonblocking(fd) 
    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on)) 
    setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&on, sizeof(on)) 
    evutil_make_listen_socket_reuseable(fd) /* Libevent call to set SO_REUSEADDR */ 
    evutil_make_socket_nonblocking(fd)  /* Libevent call to set fd non-blocking */ 
    bind(fd, (const struct sockaddr *)&sin6, sizeof(sin6)) 

필자는 fd를 특정 ipv6 주소에 바인딩하기 때문에 간헐적으로 바인드 오류가 발생합니다. 나는에서 gdb를 시도

요청 주소를 할당 할 수 없습니다,하지만 난에 gdb를 할 때마다, 바인드가 성공 - errno를 99-513 :

바인드 V6는 sin6 3FFE :: A00 실패했습니다.

왜이 문제가 발생하는지 잘 모르겠습니다. 누군가 제발 도와 줄 수 있니?

+0

Addreses 3FFE'에 ::/16' 유효하지 않습니다. 대신 유효한 IPv6 주소를 사용하십시오. –

+0

내 인터페이스에 3ffe :: 10.1.14.14/120 주소가 있습니다. 소켓을 생성하는 동안 접두사 마스크는 아무런 함의가 없습니다. 그리고 그 주소가 잘못된 이유는 무엇입니까? – shrejal

+0

유효하지 않기 때문에. 그 넷 블록은 몇 년 전에 쓸모 없어졌습니다. 그리고 그것이 전혀 사용되지 않는다는 사실은 여러분의 IPv6 설정에 무언가 잘못된 것이 있음을 나타냅니다. 먼저 수정하십시오. –

답변

0

기본적으로 소켓이 TCP 포트에 바인딩 된 후 포트는 소켓이 닫힐 때 1 분간 예약되어 있습니다.이 포트를 TCP TIME_WAIT 상태라고합니다. TIME_WAIT은 데이터 손상을 일으킬 수있는 경쟁 조건을 피할 수 있지만 일반적으로 서버 쪽에서는 TIME_WAIT을 무시하는 것이 안전합니다.

이이 SO_REUSEADDR 소켓 옵션을 설정하여 수행됩니다

int one = 1; 
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) 
+1

클리어하기 위해서, 소유하고있는 어플리케이션이 접속이 확립되어있는 동안, 소유하고있는 어플리케이션이 적극적으로 소켓을 닫을 때 소켓이'TIME_WAIT' 상태에 들어갑니다 (원격 피어가 클로우즈를 개시했을 경우, 소켓은'TIME_WAIT'를 입력하지 않습니다). 그런 다음 이전에 바인드 된 ip + 포트에 바인드하려는 NEXT 소켓에서'SO_REUSEADDR'을 활성화 할 수 있습니다. –

관련 문제