2014-12-04 21 views
6

2 ayrı sokete ihtiyacım olan bir sunucu uygulamasına sahibim - belirli bir IPv4 adresi ve sunucu bağlantı noktası X üzerinde dinleme 1 IPv4 soket yuvası ve belirli bir IPv6 adresi ve aynı sunucu bağlantı noktası X'i dinleyen bir IPv6 soketi. IPv4 ve IPv6 adresleri aynı arabirimde bulunur.IPv6 Bağlantı hataları

IPv4 soketi oluşturmak ve ona bağlanmak için evconnlistener_new_bind kullanıyorum. IPv6 dinleyicisi için kod aşağıdaki gibidir. Ben özellikle ipv6 adrese benim fd bağlamak üzere

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

, ben aralıklı bir bağlama başarısızlığı görülmektedir. Ben GDB çalıştı

istenen adresini atanamıyor ama içinde GDB her zaman, bağlama başarılı - errno 99-513:

bağlama v6 sin6 3ffe :: A00 başarısız oldu.

Bu sorunu neden görüyorum emin değilim. Birisi lütfen yardım edebilir mi?

+0

addreses 3ffe 'in ::/16 'geçerli değildir. Bunun yerine geçerli bir IPv6 adresi kullanın. –

+0

Arabirimde 3ffe :: 10.1.14.14/120 adresi var. Soketi oluştururken, önek maskesinin hiçbir anlamı yoktur? Ve neden onun geçersiz bir adresi olduğunu söylüyorsun? – shrejal

+0

Çünkü geçerli değil. Bu netblock yıllar önce geçersizdi. Ve kullanımda olduğu gerçeği IPv6 kurulumunuzda bir şeyin korkunç bir şekilde yanlış olduğunu gösteriyor. İlk önce bunu düzelt. –

cevap

0

Varsayılan olarak, bir soket bir TCP bağlantı noktasına bağlandıktan sonra, yuva kapandığında bir dakika için ayrılmış kalır - buna TCP TIME_WAIT durumu adı verilir. TIME_WAIT, veri bozulmasına neden olabilecek bazı yarış koşullarını önler, ancak sunucu tarafında TIME_WAIT'u görmezden gelmek genellikle güvenlidir.

Bu SO_REUSEADDR soket seçeneği ayarlayarak yapılır:

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

Clearify yapmak için, yerleşik bir bağlantıya sahipken sahip olma uygulaması soketi aktif olarak kapattığında bir soket 'TIME_WAIT 'durumuna girer (uzak eş konumlayıcı kapatırsa, soket' TIME_WAIT' girmez). Daha sonra, daha önce bağlı olan ip + bağlantı noktasına bağlamak istediğiniz NEXT yuvasında 'SO_REUSEADDR 'öğesini etkinleştirebilirsiniz. –