2014-06-05 1 views
-1

C에서 클라이언트/서버 프로그램 (두 프로그램이 서로 다른 컴퓨터에 있지만 localhost에는 있지 않음)을 만들려고하지만 사용 된 프로토콜은 IPv6 만 사용합니다. 클라이언트를 실행할 때 connect()에서 일시 중지 된 다음 fails.Why connect()가 실패합니다.소켓 프로그래밍 클라이언트 및 서버 프로그램이 다른 컴퓨터에있는 경우 IPv6를 사용하는 프로그래밍

서버 코드 :

#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; 
} 

클라이언트 코드 : 첫째

#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; 
} 
+1

왜 실제로? 왜 당신은 이미 페러()가 인쇄 한 것을 알 때 우리에게 왜 묻고 있습니까? 주의 : close()와 같은 다른 시스템 호출보다 먼저 호출해야합니다. – EJP

+0

사실은 오류를 인쇄하지 못했지만, 내가 perror()를 즉시 호출했다. 오류가 발생했습니다 : 연결 시간이 초과되었습니다. –

+0

실제로 오류가 인쇄되었지만 잘못되었습니다. 당신은 귀하의 질문에 모든 정보를 포함시켜야합니다. 그것없이, 그것은 대답 할 수 없다. – EJP

답변

2

, 당신은 그 링크 로컬 주소를 핑 (ping) 할 수 있습니까?
둘째, res 구조체를 채우고 그 위로 반복하지만, for 루프 내에서는 항상 반복기 인 p가 아닌 socket() 호출에 res 구조체를 사용합니다.
은 다음과 같아야합니다 : 당신은 소켓() 호출의 마지막 인수는 0하지만 p->ai_protocol 아니라는 것을 눈치 챘을 수도

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; 
} 

.

: 만의 IPv6 연결을 처리하려는 당신은 당신이 관심있는 힌트 구조에 지정된 이후, 호출한다 getaddrinfo로 잘못 알고하는 것이 좋습니다 거기에 0

보다 그것을 전달하는 안전

getaddrinfo: Name or service not known

: 오류 다음

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

내가지고 있다고 : 사람이한다 getaddrinfo에서

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

나는 getaddrinfo (나는 틀린 인터페이스를 통과하고 있었다)에게 전달하고있는 주소를 ping 할 수 없다는 것을 확인했다.

모두로, 나는 당신의 코드 작업을 관리 할 수있었습니다. 가상 컴퓨터에서 로컬 호스트에 연결할 수 있습니다. 나는 또한 내부 힌트 구조에서 우리가 관심이있는 어떤 프로토콜을 지정한 :

hints.ai_protocol = IPPROTO_TCP; 
+0

나는 클라이언트와 서버 모두에서 루프 내에서 필요한 변경을했고, hints.ai_protocol = IPPROTO_TCP; 양쪽에 ...하지만 여전히 연결 시간이 초과되었습니다 ... 나는 IPv4 주소에 의해 시스템 (서버가 속한)을 핑할 수 있지만 IPv6 one.it에는 도달 할 수 없다고 말합니다. IPv6에 도달 할 수없는 주소가 있습니다. ..왜?? –

+0

두 기계에서 "ip a"명령의 pastebin.com 결과에 붙여넣고 링크를 보내고 실행중인 ping6 명령을 알려주십시오. 어쩌면 내가 도울 수 있습니다 :) – macfij

0


내가 내 시스템에서 ping6를 통해 서버 시스템을 ping 할 수없는 이유 라우터가 IPv6.that의 지원되지 않았습니다 버렸죠 고정. 어쨌든 고마워요 :-)

+0

왜 당신은 그의 대답을 옳다고 표시 했습니까? – EJP

+0

그가 루프 내부에서 언급했기 때문에 나는 res라고 부르며 p가 아니라 그의 포스트를 체크했기 때문에 –

관련 문제