Question

I am trying to create a client/server program(both programs lies on different machine and not on localhost) in C but the protocol used is IPv6 only. when i run the client,it pauses for sometime at the connect() and then fails.Why connect() is failing?

Server Code:

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<unistd.h>
#include<netdb.h>
int main()
{
 int sockfd,connfd,rv;
 struct addrinfo hints,*servinfo,*p;
 struct sockaddr_in6 client_addr;

 memset(&hints,0,sizeof hints);

 hints.ai_family=AF_INET6;
 hints.ai_socktype=SOCK_STREAM;
 hints.ai_flags=AI_PASSIVE;


 if((rv=getaddrinfo(NULL,"8888",&hints,&servinfo))!=0)
 {      printf("\n Error 1 \n"); return 0; }


for(p=servinfo;p!=NULL;p=p->ai_next)
{

 if((sockfd=socket(servinfo->ai_family,servinfo->ai_socktype,0))==-1)
 {      perror("socket"); continue;}

 if(bind(sockfd,servinfo->ai_addr,servinfo->ai_addrlen)==-1)
 {      close(sockfd); perror("bind"); continue;}

  break;
}
 if(p==NULL)
{
 fprintf(stderr,"failed to bind");
 return 0;
}

  listen(sockfd,8);

  printf("\n\n Waiting for connection....\n");

  socklen_t size=sizeof(client_addr);

  if((connfd=accept(sockfd,(struct sockaddr *)&client_addr,&size))<0)
  {     printf("\n Error 4 \n"); return 0; }
  else
  {
       char ch[50];
       inet_ntop(AF_INET6,&(client_addr.sin6_addr),ch,50);
       printf("\n Connected to %s \n",ch);
  }

  close(sockfd);
  close(connfd);

  return 0;
}

Client Code:

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<unistd.h>
#include<netdb.h>
int main()
{
 int i,s;

 struct addrinfo hints,*res,*p;

 memset(&hints,0,sizeof (hints));

 hints.ai_family=AF_INET6;
 hints.ai_socktype=SOCK_STREAM;

 i=getaddrinfo("fe80::20c:29ff:fe60:7593%eth0","8888",&hints,&res);//because the system in which server code is has IPv6 address fe80::20c:29ff:fe60:7593

 if(i!=0)
  { printf("\n Fail 1 \n"); return 0;}

 for(p=res;p!=NULL;p=p->ai_next)
 { 
   if((s=socket(res->ai_family,res->ai_socktype,0))==-1)
    {perror("socket"); continue;}

   if(connect(s,p->ai_addr,p->ai_addrlen)==-1)
    { close(s); perror("connect"); continue;}

   break;
 }

 if(p==NULL)
 {
  fprintf(stderr,"failed to connect\n");
   return 0;
  }

 close(s);
 return 0;
}
Était-ce utile?

La solution

firstly, can you ping that link-local address?
secondly, you are filling res structure and then iterating over it, but inside your for loop you always use res structure for socket() call, not p, which is your iterator.
it should look like this:

for(p=res;p!=NULL;p=p->ai_next)
 { 
   if((s=socket(p->ai_family,p->ai_socktype,p->ai_protocol))==-1)
    {perror("socket"); continue;}

   if(connect(s,p->ai_addr,p->ai_addrlen)==-1)
    { close(s); perror("connect"); continue;}

   break;
 }

you might have noticed that last argument of socket() call is not 0, but p->ai_protocol. since you want to handle only ipv6 connections and you specified in hints structure that you're interested in it, it is safer to pass it than 0.

there's a good practice to know what was wrong with calling getaddrinfo :

if(i!=0){                                                                  
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(i));                
    return 1;                                                            
}

from man getaddrinfo:

The gai_strerror() function translates these error codes to a human readable string, suitable for error reporting.

I was getting following error:

getaddrinfo: Name or service not known

I checked that i was not able to ping address that i was passing to getaddrinfo (i was passing wrong interface).

all in all, i managed to got your code working. i can connect from virtual machine to localhost. i have also specified what protocol are we interested in inside hints structure:

hints.ai_protocol = IPPROTO_TCP;

Autres conseils

I fixed it.Actually the router was not supporting IPv6.that's why i was unable to ping the server system via ping6 from my system. Thanks anyways macfji :-)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top