2010-05-06 13 views
1

두 대의 컴퓨터가 있습니다. 내 코드를 테스트하고 있습니다. 하나는 정상적으로 작동하고 다른 하나는 문제가 있으며 그 이유를 알 수 없습니다.sendto : 네트워크에 연결할 수 없습니다.

저는 프로젝트의 네트워킹 부분에 개체 (C++)를 사용하고 있습니다. 서버 쪽에서 나는 이렇게한다 : (명확성을 위해 오류 검사를 제거했다)

 res = getaddrinfo(NULL, port, &hints, &server)) < 0 

    for(p=server; p!=NULL; p=p->ai_next){ 
      fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); 
      if(fd<0){ 
        continue; 
        } 

      if(bind(fd, p->ai_addr, p->ai_addrlen)<0){ 
        close(fd); 
        continue; 
        } 
      break; 
      } 

이 모든 것이 작동한다. 그런 다음이 생성자를 사용하여 객체를 만듭니다.

net::net(int fd, struct sockaddr *other, socklen_t *other_len){ 
     int counter; 
     this->fd = fd; 
     if(other != NULL){ 
       this->other.sa_family = other->sa_family; 
       for(counter=0;counter<13;counter++) 
         this->other.sa_data[counter]=other->sa_data[counter]; 
       } 
     else 
       cerr << "Networking error" << endl; 
     this->other_len = *other_len; 
     } 

void net::gsend(string s){ 
     if(sendto(this->fd, s.c_str(), s.size()+1, 0, &(this->other), this->other_len)<0){ 
       cerr << "Error Sending, " << s << endl; 
       cerr << strerror(errno) << endl; 
       } 
     return; 
     } 

    string net::grecv(){ 
     stringstream ss; 
     string s; 
     char buf[BUFSIZE]; 
     buf[BUFSIZE-1] = '\0'; 

     if(recvfrom(this->fd, buf, BUFSIZE-1, 0, &(this->other), &(this->other_len))<0){ 
       cerr << "Error Recieving\n"; 
       cerr << strerror(errno) << endl; 
       } 

     // convert to c++ string and if there are multiple trailing ';' remove them 
     ss << buf; 
     s=ss.str(); 
     while(s.find(";;", s.size()-2) != string::npos) 
       s.erase(s.size()-1,1); 
     return s; 
     }  

내 문제는 하나의 시스템에서 모든 것이 정상적으로 작동한다는 것입니다. 다른 하나는 서버의 gsend() 함수를 호출 할 때까지 모든 것이 잘 작동합니다. "오류 : 네트워크에 연결할 수 없습니다."라는 메시지가 나타납니다. gercend()를 호출하기 전에 먼저 gercv()를 호출합니다. 누구든지 나를 도울 수 있습니까? 나는 정말로 감사 할 것입니다.

솔루션은

이 서버가 나는 초기 SOCKADDR 구조를 설정하는 방법을 좋아하지 않는 것으로 나타났다. 나는이 일을했다 :

 struct addrinfo hints; 
    memset(&hints, 0, sizeof(struct addrinfo)); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_DGRAM; 
    hints.ai_flags = AI_PASSIVE; 
    hints.ai_protocol = IPPROTO_UDP; 

이 같이 있었어야 할 때

 struct addrinfo hints; 
    memset(&hints, 0, sizeof(struct addrinfo)); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_DGRAM; 

사람이 이것을 설명 할 수 있습니까?

+0

이 오류가 발생한 프로그램이 아니라고 확인했다고 가정합니다. google.com 또는 보내려는 기계에 ping 할 수 있는지 확인 했습니까?코드 문제보다 서버 문제와 비슷합니다. – Glen

+0

문제가있는 시스템에 ssh가있어서 문제가되지 않습니다. – devin

답변

0

확인할 사항 없음 1. 서버를 실행합니다. netstat을 사용하여 서버가 바인딩 된 IP와 포트를 확인하십시오. IP는 로컬 호스트 IP인가 아니면 0.0.0.0 IP인가? 2. 서버가 올바른 포트에서 수신 대기 중이며 주소가 정상이면 포트에 텔넷 할 수 있는지 확인하십시오. 그냥이 telnet을 시도하십시오 3.이 포트에 연결을 시도합니다 (연결이 telnet 서버가 아니라도 상관 없습니다). 4. telnet이 포트에 연결할 수 있으면 no 오류가 있으면 클라이언트 코드를 검사하여 누락 된 부분을 확인할 수 있습니다. Glen이 언급 한 것처럼 클라이언트 시스템에서 원격 연결을 할 수 있는지 확인 했습니까?

0

소켓을 만들고 바인딩 할 수있는 첫 번째 인터페이스를 선택하여 서버가 수신하는 인터페이스를 선택하는 것처럼 보입니까? 이것은 새로운 방법으로 보입니다 ...

확실하게, 여러 개의 NIC가있는 머신에서는 확실히 하나가 아닌 다른 것에 바인딩하려는 경향이 있습니다. 그리고 원하는 것을 어느 정도 알기 쉽습니다. 예를 들어, 우리가 2 개의 NIC를 가지고 있고, 하나는 인터넷을 향하고 있고 다른 하나는 내부 사설망을 마주하고 있다면 당신은 당신이 바인딩하고 서비스를 제공하고자하는 인터페이스를 알고있을 것입니다. 그리고 코드가 무엇을하고있는 것처럼 보입니까? 둘 다에 대한 소켓을 만들 수 있습니다 ...

어쨌든, 당신은 당신이 보낼 수없는 컴퓨터에서 연결을 할 수없는 네트워크를 가리키는 인터페이스에 바인딩하고 있다고 상상할 것입니다 당신의 목표 주소 ... 당신이 그 소켓과 코드 스 니펫에서 데이터를받을 수 있다고 말했기 때문에 나는 당신이 방금받은 주소로 다시 보내려한다고 가정합니다. 문제가 발생했을 때 계속 실행 중이고 설치가 잘못되어 대상 시스템으로 연결될 수는 없지만 대상 시스템이 서버로 라우팅 할 수 있습니다 ...

관련 문제