In my program, I am trying to implement support for dual-stack operation (both IPv4 and IPv6 sockets).
In the case of IPv4, everything is working fine. But in the IPv6 case, accept()
is returning a -开发者_JS百科1
value (an error).
Can anyone suggest the possible reasons, and how to fix it?
When accept()
returns -1
, errno
will be set to indicate what specific error occurred. Please call perror("accept")
for an easy way to see what the error was, and update your question with the results.
Also, please note that accept()
must be called on a socket that has been:
- Created using the
socket()
call. (you should passPF_INET6
for the first argument of your socket to create an IPv6 protocol family socket) - Bound, using
bind()
using astruct sockaddr_in6
parameter as the 2nd parameter (with itssin6_family
set toAF_INET6
for IPv6 to indicate you will be binding to an IPv6 address). Remember to zero out thesin6_zero
field first. One strategy would be to zero the entire sockaddr structure, which would set the IPv6 address to IN6ADDR_ANY, which means you would just have to set the port and the address family. - Listening, by means of calling
listen()
If you are still having trouble, post the code you have so far.
If I had to guess (since you haven't posted any code), I think if it works with IPv4 and gets to the point where it can accept()
a connection, but IPv6 connection accept()
calls return -1
, I think it's likely that you aren't passing accept()
a large enough struct sockaddr
for it to work.
For example, the following code:
printf("sizeof(struct sockaddr_in) = %ld\n", sizeof(struct sockaddr_in));
printf("sizeof(struct sockaddr_in6) = %ld\n", sizeof(struct sockaddr_in6));
Prints (on my system):
sizeof(struct sockaddr_in) = 16
sizeof(struct sockaddr_in6) = 28
If you are only giving accept()
enough room to write out an IPv4 address, it will fail when it accepts an IPv6 connection. Make sure you allocate either a struct sockaddr_in6
or a struct sockaddr_storage
, and ensure the size argument is correct.
精彩评论