2014-12-04 17 views
6

Tôi có một máy chủ thực hiện nơi tôi cần 2 ổ cắm riêng biệt - 1 ổ cắm IPv4 nghe trên địa chỉ IPv4 và cổng máy chủ X cụ thể và ổ cắm IPv6 nghe trên địa chỉ IPv6 cụ thể và cùng cổng máy chủ X. Địa chỉ IPv4 và IPv6 nằm trên cùng một giao diện.IPv6 Lỗi kết nối

memset(&sin, 0, sizeof(sin)); 
    sin.sin_family  = AF_INET; 
    sin.sin_addr.s_addr = htonl(v4addr); 
    sin.sin_port  = htons(tcp_port); 

Tôi đang sử dụng evconnlistener_new_bind để tạo ổ cắm ipv4 và liên kết với nó. Đối với trình nghe IPv6, mã như sau.

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)) 

Khi tôi liên kết fd với địa chỉ ipv6 cụ thể, tôi thấy lỗi liên kết không liên tục.

bind v6 thất bại 3ffe sin6 :: a00: 513 - errno 99 - Không thể gán địa chỉ yêu cầu

Tôi cố gắng để gdb, nhưng mỗi khi tôi gdb trong, các ràng buộc thành công.

Tôi không chắc tại sao tôi lại gặp sự cố này. Ai đó có thể giúp đỡ?

+0

Addreses trong '3ffe ::/16' không hợp lệ. Sử dụng địa chỉ IPv6 hợp lệ để thay thế. –

+0

Giao diện của tôi có địa chỉ 3ffe :: 10.1.14.14/120. Trong khi tạo ổ cắm, mặt nạ tiền tố không có tác động đúng không? Và tại sao bạn lại nói địa chỉ không hợp lệ của nó? – shrejal

+0

Vì nó không hợp lệ. Rằng netblock đã lỗi thời năm trước. Và thực tế là nó đang được sử dụng ở tất cả chỉ ra rằng một cái gì đó là khủng khiếp sai với thiết lập IPv6 của bạn. Khắc phục điều đó trước. –

Trả lời

0

Theo mặc định, sau khi ổ cắm bị ràng buộc vào cổng TCP, cổng vẫn được đặt trước trong một phút khi đóng socket - đây được gọi là trạng thái TCP TIME_WAIT. TIME_WAIT tránh một số điều kiện chủng tộc có thể gây hỏng dữ liệu, nhưng thường an toàn khi bỏ qua TIME_WAIT ở phía máy chủ.

này được thực hiện bằng cách thiết lập các tùy chọn SO_REUSEADDR ổ cắm:

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

Để làm rõ, một ổ cắm vào trạng thái 'TIME_WAIT' khi ứng dụng sở hữu tích cực đóng socket trong khi nó có kết nối được thiết lập (nếu đồng đẳng từ xa bắt đầu đóng, socket sẽ không vào' TIME_WAIT'). Sau đó bạn có thể bật 'SO_REUSEADDR' trên ổ cắm NEXT mà bạn muốn liên kết với cổng ip + bị ràng buộc trước đó. –