2016-10-07 6 views
0

내 워크 스테이션 (192.168.0.1)과 내 WinCE6 장치 (192.168.0.100) 사이의 이더넷 인터페이스를 통해 UDP 소켓으로 작업하고 있습니다.C++ Winsock UDP sendto는 성공했지만 전송되는 데이터가 표시되지 않습니다.

내 워크 스테이션에서 수신 소켓을 설정하고 포트 9002에서 데이터를 올바르게 수신하는 WinCE 장치로 UDP 패킷을 보낼 수 있습니다. 그런 다음 장치는 데이터를 내 워크 스테이션에 적절하게 다시 에코합니다.

가 내 장치가 특정 포트에 내 워크 스테이션에 응답 할 : 내 장치에 실행하는 서버가

9001, 그것은 this과 동일하지만 난의 주소에 소켓 바인드 수정

#define BUFLEN 512 //Max length of buffer 
#define PORT 9002 //The port on which to listen for incoming data 

void test_udp(void) 
{ 
SOCKET s; 
struct sockaddr_in server, si_other; 
int slen , recv_len; 
char buf[BUFLEN]; 
WSADATA wsa; 

slen = sizeof(si_other) ; 

//Initialise winsock 
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) 
{ 
    return; 
} 

//Create a socket 
if((s = socket(AF_INET , SOCK_DGRAM , 0)) == INVALID_SOCKET) 
{ 
    printf("Could not create socket : %d" , WSAGetLastError()); 
} 

//Prepare the sockaddr_in structure 
server.sin_family = AF_INET; 
server.sin_addr.s_addr = htonl(0xC0A80064); 
server.sin_port = htons(PORT); 

//Bind 
if(bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR) 
{ 
    return; 
} 

//keep listening for data 
while(1) 
{ 
    //clear the buffer by filling null, it might have previously received data 
    memset(buf,'\0', BUFLEN); 

    //try to receive some data, this is a blocking call 
    if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR) 
    { 
     return; 
    } 

    // *** CHANGE THE SEND PORT 
    si_other.sin_port = htons(9001); 

    //now reply the client with the same data 
    if (sendto(s, buf, recv_len, 0, (struct sockaddr*) &si_other, slen) == SOCKET_ERROR) 
    { 
     return; 
    } 
} 

closesocket(s); 
WSACleanup(); 

return; 
} 

내가, 내가 수와 일치 sendto를위한 적절한 반환 값을 얻고 다시 포트 9001에 데이터를 보내려고하는 // *** CHANGE THE SEND PORT 주석 아래의 라인을 추가하는 경우 : 특정 인터페이스와 나는 PORT 정의 변경 내가 예상했던 바이트 수 엔트이지만 데이터가 내 워크 스테이션에 오는 것을 보지 못했습니다 (9001 듣기).

나는 이것에 대한 내 머리를 두드리고 있었는데 나는 틀린 것을 본다. 수정 된 예제에서 어떤 도움이라도 대단히 감사하겠습니다.

업데이트 : 개발 PC의 방화벽이 잘못되었습니다. 그것은 PC가 보내고 있던 동일한 포트에서 다시 트래픽을 허용했지만 다른 포트에서는 트래픽을 차단했습니다. 코드를 변경하지 않고 트래픽을 전송할 수있는 해결. 이전에 방화벽을 비활성화했지만 OS가 방화벽을 활성화 한 "공용 네트워크"로 이더넷을 지정했는지는 알지 못했습니다.

+0

수신 프로그램이 작동하는지 어떻게 알 수 있습니까? wireshark를 사용하여 무엇이 전선에 부딪 치는 지 보셨습니까? 'sendto()'의 리턴 코드를 출력하면 실패했는지 그렇지 않은지를 알기가 어려울 것이기 때문에 또한 도움이 될 것입니다. –

+0

첫 번째로해야 할 일은 bind를 검사하고 WSAGetLastError를 사용하는 것입니다. 어떤 페이스 체크에서 두 번째로 인쇄 할 때 : 예를 들어 메시지를 받았다면. 차단 기능을 사용하여 송수신하십시오. 가장 좋은 방법은 내가 udp 소켓과 멀티 쓰레딩을 사용하여 채팅 프로그램을 만들었습니다. – Raindrop7

+0

왜 'sin_port'를 바꾸고 있습니까? 그것은'recvfrom()'다음에 송신 포트 번호를 이미 포함 할 것입니다. 그것이 당신이 대답하고 싶은 항구입니다. 해당 행을 제거하십시오. – EJP

답변

-1

sendto에서 SOCKET_ERROR가 표시되지 않고 적절한 반환 값이 표시되면 OS가 대상 IP 방향의 경로를 찾을 수 있었고 보내기를 버퍼링 할 수 있었음을 의미합니다 의뢰.

송신 포트를 변경하려면 데이터가 수신 된 포트와 관련하여 다른 포트에 응답하고 싶다면이지만 이는 일반적인 경우는 아닙니다. 실제로 si_other 구조체는 recvfrom 다음에 소스 주소를 포함하므로 소스 포트도 포함합니다. 코드를 장치 측에 그대로 두십시오.

워크 스테이션에 데이터가 흐려 보이지 않는 경우 개발 환경으로 간단한 네트워킹 컨텍스트에서 워크 스테이션에 문제가 발생했습니다 : 데이터가 수신되지 않음.
나는 패킷에 무슨 일이 일어나고 있는지 와이어 셔크 (WireShark)와 조사해야한다는 @ 다니엘의 의견에 동의합니다.

희망 하시겠습니까?

+1

1. 보내기에서 오류가 발생하지 않는다면 대상 호스트 : 포트가 있음을 의미하지는 않습니다. 단지 호스트에 대한 경로가 있었고 데이터 그램이 전송을 위해 버퍼링되었다는 것을 의미합니다. 2.'sin_port'를 설정하는 것은 좋지 않습니다. 시간 낭비입니다. 응답에 대한 올바른 값으로 이미 설정되어 있습니다. '당신이 그 주소에 대답한다면 당신은 원산지 항구에 대답 할 것입니다.'당신이하고 싶은 바로 그 것입니다. 'sin_port'를 고정 값으로 설정하면 잘못된 값을 설정하거나 올바른 값을 변경하지 않습니다. – EJP

+0

감사합니다. EJP. 그러나 나는 왜 sin_port를 변경하면 잘못된 값을 설정하거나 변경하지 않는다고 말하는지 이해하지 못합니다. 이것은 우리가받은 포트와 다른 포트에 응답하는 전형적인 경우는 아니지만 여전히 가능합니다. – salvolds

+0

'sin_port'는 들어오는 데이터 그램을 포팅 한 소스를 포함합니다. 응답해야하는 포트. 그것을 설정하는 데는 아무런 의미가 없습니다. 설정 한 값이 잘못되었거나 응답이 도착하지 않거나 올바르게 설정된 경우 아무 것도 설정하지 않은 채 값을 변경하지 않았습니다. 이것은 다소 명백한 것처럼 보입니다. 피어가 두 개의 포트를 사용한다는 증거는 없으므로 코드를 보관할 것을 권장 할 이유가 없습니다. – EJP