2011-09-26 3 views
1

나는 서버 - 클라이언트 프로그램을 작성하고 서버에서 getaddrinfo 및 getsockname을 사용하여 로컬 IP 주소 및 로컬로 연결된 포트 번호에 대한 정보를 얻습니다. 이 정보를 사용하여 클라이언트 프로그램을 시작하고 getaddrinfo를 사용한 다음 servinfo 데이터 구조에 반환 된 값을 출력합니다. getaddrinfo (argc [1], argc [2], & 힌트, & servinfo); >> 서버 호스트 이름과 서버 포트 번호는 명령 행을 통해 전달됩니다.죄송합니다 getaddrinfo에 반환 된

하지만 servinfo의 sin_port가 명령 줄을 통해 전달하는 포트가 아니라는 것을 알았습니다. 1)이 getaddrinfo는 클라이언트가 소스 포트 번호로 사용하는 포트 번호를 반환합니까? 2) getaddrinfo 및 소켓 호출이 실패한 후 연결 호출이 실패합니다. 나는 이유를 모른다. 어떻게 디버깅합니까?

내 클라이언트 코드 :

memset(&hints, 0 ,sizeof hints); 
hints.ai_family = AF_INET; 
hints.ai_socktype = SOCK_STREAM; 
hints.ai_flags = AI_CANONNAME | AI_NUMERICSERV; 
getaddrinfo(argc[1], argc[2], &hints, &servinfo); 

for (p = servinfo till p!=NULL) 
    sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol) 
    connect(sockfd, p->ai_addr, p->ai_addrlen) >>>>> Connect not going through. 

나는이처럼 내 클라이언트 프로그램을 시작 를 myservername ./a.out 18,844

감사합니다!

+0

getaddrinfo()가 오류와 함께 실패하지 않았다는 것을 어떻게 알 수 있습니까? 반환 값이 0인지 아닌지 확인하지 않습니다. gettaddrinfo()가 실패하면 당연히 출력 인수에 데이터가 기록되지 않습니다. –

+0

나는 그것을 servername과 함께 호출하고있다. 그러나 그것을 놓친 것은 문제 설명에 그것을 추가합니다. – Vin

+0

getaddrinfo의 리턴 코드를 확인해야합니다. 그것은 servinfo 구조에서 반환되는 IPv4 주소를 읽을 수 있기 때문에 실패하지 않아야합니다. – Vin

답변

4

새로운 대답은 : 당신은 하나의 인수와 함께 프로그램을 호출, 그래서 argv[1]"18844" 포함하고 argv[2]는 널 포인터이다. 이것은 숫자 IP 18844와 지정되지 않은 포트 번호로 호스트에 연결을 시도합니다 (결국 0이되고 실패합니다).

올드 답 : (관련 아니지만 문제) sin_port 전체 sockaddr_in 구조가 네트워크 바이트 순서입니다. 숫자로 사용하려면 ntohl으로 포트를 변환해야하지만 sockaddr 구조의 내부를 전혀 만지지 않는 것이 좋습니다. 대신 getnameinfoNI_NUMERICHOSTNI_NUMERICSERV을 사용하여 주소를 문자열 기반 숫자 형식으로 다시 가져오고 strtol을 사용하여 포트 ("서비스") 번호를 정수로 읽습니다. 이는 IPv6와 같은 비 IPv4 네트워크 주소/프로토콜 제품군에도 적용되며 새로운 프로토콜을 지원하기위한 추가 코드가 필요하지 않습니다.

+0

'argc'는 보통'argv' 배열에 사용되는 이름이 아닙니다. –

+0

나는 그것을 시도 할 것이다. 하지만 sin_port가 클라이언트 포트입니까? 또는 명령 줄을 통과하는 서버 포트와 동일해야합니까? 미안하지만, 나는 너무 혼란 스럽다. – Vin

+0

p> ai_addr을 connect()에 전달하여 서버 주소 인 * to *에 연결할 주소로 사용합니다.언급했듯이 strace를 통해 코드를 실행하면 connect()가 호출 된 인수가 표시되어야합니다. – nos

관련 문제