2016-10-07 1 views
0

Я работаю с сокетами UDP через интерфейс Ethernet между моей рабочей станцией (192.168.0.1) и моим устройством WinCE6 (192.168.0.100).C++ Winsock UDP sendto успешно завершен, но я не вижу отправки данных

С моей рабочей станции я могу отправить UDP-пакеты к моему устройству WinCE, где у меня установлен приемный сокет и правильно принимаю данные на порту 9002; устройство затем правильно отсылает данные на мою рабочую станцию.

Я хочу, чтобы мое устройство, чтобы ответить на мою рабочую станцию ​​на конкретный порт: 9001.

Это сервер работает в устройство, это то же самое, как this но я модифицировал сокет связывается с адресом из специальный интерфейс, и я изменил PORT определить:

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

Когда я добавил строку ниже // *** CHANGE THE SEND PORT комментарий, чтобы попытаться отправить данные в порт 9001, я получаю соответствующее возвращаемое значение для SendTo, который соответствует номеру байтов, которые я ожидал но я не вижу данные, поступающие на мою рабочую станцию ​​(прослушивание по 9001).

Я ударил головой об этом, и я не вижу ничего плохого. В модифицированном примере любая помощь будет принята с благодарностью.

ОБНОВЛЕНИЕ: Брандмауэр на моем компьютере разработки был виноват. Это позволило вернуть трафик на тот же порт, на который был отправлен мой компьютер, но заблокировал трафик на любом другом порту. Разрешение, позволяющее отправлять трафик без изменений кода. Ранее я отключил брандмауэр, но не понял, что ОС помешала ethernet как «общедоступную сеть», в которой все еще был включен брандмауэр.

+0

Как вы знаете, что ваша приемная программа работает? Вы пробовали использовать wirehark, чтобы увидеть, что попадает на провод? Было бы также полезно, если бы вы распечатали код возврата 'sendto()', потому что будет сложно определить, не получилось ли это или нет. –

+0

Первое, что нужно сделать, это проверить привязку и использовать WSAGetLastError. во-вторых, при любой проверке темпа при печати, например: если вы получаете сообщение или нет. используйте функцию блокировки для приема и отправки. лучшее, что я делал, я сделал чат-программу, используя udp-сокеты и многопоточность. – Raindrop7

+0

Почему вы меняете 'sin_port'? Он уже будет содержать номер отправляющего порта после 'recvfrom()'. Это порт, на который вы хотите ответить. Удалите эту строку. – EJP

ответ

-1

Если, как вы сказали, вы не получаете SOCKET_ERROR из sendto, и вы видите соответствующее возвращаемое значение, это означает, что ваша ОС смогла найти маршрут к целевому IP-адресу и смогла заблокировать вашу отправку запрос.

Чтобы изменить порт отправки, это нормально, если вы хотите ответить на другой порт относительно того, из которого вы получили данные, но обратите внимание, что это не типичный случай; структура si_other на самом деле будет содержать адрес источника после recvfrom и, следовательно, исходный порт. Так что держите свой код так, как он со стороны вашего устройства.

Если вы не видите данные, передаваемые на рабочую станцию, вероятно, в простом контексте сетей как среды разработки, проблема на рабочей станции: она не получает данные.
Я согласен с @ Даниэлем, что вы должны исследовать с помощью WireShark, чтобы узнать, что происходит с пакетами.

Надеюсь, что это поможет

+1

1. Если вы не получили ошибку при отправке, это не означает, что целевой хост: порт был найден. Это означает только, что был маршрут к хосту и что датаграмма получила буферизацию для отправки. 2. Установка 'sin_port' не является хорошей: это пустая трата времени. Он уже настроен на правильное значение для ответа. «Если бы вы ответили на этот адрес, вы ответили бы на исходный порт», это именно то, что вы хотите сделать. Установка 'sin_port' некоторого фиксированного значения либо устанавливает неправильное значение, либо не изменяет правильное значение. – EJP

+0

Спасибо EJP. Но я не понимаю, почему вы говорите, что изменение sin_port устанавливает неправильное значение или не меняет его. Это не типичный случай для ответа на другой порт, чем тот, который мы получили, но все же это возможно ... – salvolds

+0

'sin_port' содержит источник, портированный входящей дейтаграммой. Порт, на который вы должны ответить. Нет смысла устанавливать его вообще. Либо значение, которое вы установили, неверно, и в этом случае ответ не поступит, или он прав, и в этом случае он ничего не установил - он не изменил значение. Это кажется довольно очевидным. В вопросе нет доказательств того, что одноранговый узел использует два порта, и поэтому нет причин для рекомендации по сохранению кода. – EJP

Смежные вопросы