2014-12-22 2 views
1

그래서 저는 뭔가를 놓치고 있지 않은지 확인하고 싶었습니다.recvfrom은 클라이언트로부터 아무런 메시지도받지 못했지만 클라이언트는 정보를 보내고 있습니다

UDP_Msg mensajeRecibidoUdp; 
struct sockaddr_in c_ain; 
sock_udp=socket(AF_INET,SOCK_DGRAM,0); 
struct sockaddr_in c_ain; 
socklen_t tam_dir;  

while(1) 
{ 
    if(recvfrom(sock_udp, &mensajeRecibidoUdp, sizeof(UDP_Msg), 0, 
     (struct sockaddr*) &c_ain, &tam_dir) <0) 
.... 

문제는 메시지가 도착하기를 기다립니다이다 :

내가 가진 코드의 일부이다. 그리고 메시지가 전송되지만이 코드는 아무 것도 얻지 못합니다.

간단한 연습이며 클라이언트가 이미 구축되었습니다. 그것은 파일에서 포트를 가져 와서 몇 int와 배열을 가진 구조체 인 UDP_Message를 보낸다 (클라이언트는 이미 IP와 포트를 알고있다).

내가 버퍼를 처리하는 방식이 잘못 될 수 있다고 생각했지만, 내가 본 모든 예제에서는 이와 같이 사용합니다. 나는 또한 c_ain 변수가 초기화 될 필요가 있다고 생각했지만, 제대로 이해한다면 그렇지 않다. 따라서 프로세스가 차단되는 이유를 알 수 없습니다. 적절한 단어가 무엇인지 확신 할 수 없으며 많은 시간이 지나가고 알람이 울리며 프로세스가 종료됩니다 (정보가 있어야하고 유지해야하기 때문에). 코드가 아니라).

다른 많은 정보를 추가 할 수 있습니다. 짧게 유지하려고했습니다. 나는 클라이언트 - 서버 기능을 실행할 때 어떻게 작동하는지에 따라 호출이 제대로 작동하지 않는다는 것을 알고 있습니다.

편집 : 바인딩 :

bzero((char*)&dir_udp_serv,sizeof(struct sockaddr_in));    
    dir_udp_serv.sin_family=AF_INET; 
    dir_udp_serv.sin_addr.s_addr=inet_addr(HOST_SERVIDOR); 
    dir_udp_serv.sin_port=0;    
    fprintf(stderr,"SERVIDOR: Asignacion del puerto servidor: "); 
    if(bind(sock_udp, 
     (struct sockaddr*)&dir_udp_serv, 
     sizeof(struct sockaddr_in))<0) 
    { 
     fprintf(stderr,"ERROR\n");     
     close(sock_udp); exit(1); 
    } 

두 번째 편집 : 난 그냥 코드에 두 개의 바인딩을 깨달았다. 생각은 동일한 서버에 두 개의 연결을 만듭니다. 하나는 UDP 용이고 다른 하나는 TCP 용입니다. 그래서 UDP와 TCP 모두 동일한 단계를 밟았습니다. 대답에서 나는 그것이 틀릴 수도 있음을 깨닫게되었습니다. UDp 용 소켓 하나와 TCP 용 소켓 두 개를 만들더라도 소켓 당 단 하나의 바인드일까요?

위와 같은 경우는 아닙니다.

또한 추가해야 할 세부 정보가 무엇인지 모르겠지만 서버와 클라이언트는 모두 같은 컴퓨터에 있으므로 주소는 모두 127.0.0.1이지만 예상대로입니다. 왜 서버는 클라이언트로부터 전송 된 정보를 얻지 못합니다.

답변

2

자신에게 물어보십시오 : 클라이언트가 메시지를 보내는 포트는 무엇입니까? 서버 코드의 해당 포트는 어디에 있습니까? 아무데도. 로컬 소켓을 로컬 주소 (및 포트)에 바인딩하는 것을 잊어 버렸습니다.

struct sockaddr_in local; 
local.sin_family = AF_INET; 
local.sin_addr.s_addr = inet_addr("0.0.0.0"); 
local.sin_port = htons(PORT); // Now the server will listen on PORT. 

if(bind(sock_udp, (struct sockaddr*)&local, sizeof(local)) < 0){ 
    perror("bind"); 
    exit(1); 
} 

// Now you may call recvfrom on your socket : your server is truly listening. 

한 번만 바인딩하면됩니다. 루프에 넣을 필요가 없습니다.

+0

내가 말했듯이, 코드가 쓸데없는 것 같아 나중에 코드를 작성하지 않았지만 나중에 바인딩이 중요하다는 것을 알게되었습니다. 나는 코드에이 코드를 가지고 있는데, 이것은 가지고있는 코드이고 꽤 유사하다고 생각한다. 주석은 많은 문자를 사용할 수 없기 때문에 메인 포스트에 추가 할 것이다. – keont

+1

@keont하지만 포트 0에 바인딩되어 있습니다. 즉, 커널이 _random_ 포트를 선택할 것입니다 (AFAICR). 이 답변에 따라 특정 포트를 선택해야합니다. – Alnitak

+0

'INADDR_ANY' 매크로는'inet_addr ("0.0.0.0")보다 더 일반적입니다. – Alnitak

-1

이 장소가 아닌지 잘 모르겠지만 내 질문에 대한 대답은 예상 한 것입니다. 서버가 포트에서 수신 중이며 클라이언트가 다른 수신자에게 전송 중입니다. 이는 할당 된 포트가 클라이언트에 전송 된 방식 때문입니다. 제 경우에는 네트워크 형식 (ntohs())으로 변환하지 않고 클라이언트가 htons()를 수행했을 때 수는 완전히 다른 수입니다.

+0

클라이언트에 포트를 보내는 것은 코드에 표시되지 않고 동일한 질문을 다시 역으로 만 제기합니다. 서버는 클라이언트의 포트를 알아야합니다. 번호는 클라이언트에게 자신의 포트 번호를 보낼 수 있습니다. 어딘가에 이것은 멈추고 포트 번호를 사용하는 대신 초기 포트 번호를 코딩해야합니다 . – EJP

+0

그건 ... 잘 모르겠지만, 클라이언트가 당신에게 연결되면, 누가 당신에게 연결하고 있는지 정보를 저장할 수 있습니다. recvfrom에서, 그것은 5 번째 매개 변수 어 ... 당신이 원하는 정보를 자유롭게 보낼 수 있도록 그 정보를 저장합니다 ... 그리고 다시, 아무도 포트 0을 사용하지 않습니다. 0을 사용할 때 임의의 포트를 얻습니다. 나중에 알 수 있습니다. getsockname()과 함께했습니다. 제가 말하고자하는 것은, 당신이 말하는 것을 이해하지 못하거나, 당신이 요점을 놓치고 있고, 옳지 않은 채 저를 downvoting하는 것입니다. – keont

관련 문제