2016-07-07 1 views
0

У меня проблема, потому что мой сервер не получает данные UDP. Порты на маршрутизаторе перенаправляются, доходы данных в сеть локального сервера (это видно на сниффер (3)), но сервер не получает его.C++ WINSOCK recvfrom no получить данные из сети

Server and server network screen

Вы можете видеть, 1 и 2 TCP-пакеты правильный доход сервера на подключенных сокетов. Но мой клиент затем отправляет данные UDP на сервер и данные, входящие в сеть локального сервера (см., Что снифер обнаруживает его на 3), но сервер не принимает его.

Вот код клиента:

struct sockaddr_in si_other; 
int s, slen = sizeof(si_other); 
char buf[10]; 
char message[10]; 
WSADATA wsa; 

//Initialise winsock 
printf("\nInitialising Winsock..."); 
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 
{ 
    printf("Failed. Error Code : %d", WSAGetLastError()); 
    exit(EXIT_FAILURE); 
} 
printf("Initialised.\n"); 

//create socket 
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR) 
{ 
    printf("socket() failed with error code : %d", WSAGetLastError()); 
    exit(EXIT_FAILURE); 
} 

//setup address structure 
memset((char *)&si_other, 0, sizeof(si_other)); 
si_other.sin_family = AF_INET; 
si_other.sin_port = htons(14996); 
si_other.sin_addr.S_un.S_addr = inet_addr(server ip); 

memcpy(message, "cokolwiek", 8); 

//send the message 
if (sendto(s, message, strlen(message), 0, (struct sockaddr *) &si_other, slen) == SOCKET_ERROR) 
{ 
    printf("sendto() failed with error code : %d", WSAGetLastError()); 
    exit(EXIT_FAILURE); 
} 

Но это не проблема с клиентом. Вот код сервера, но я думаю, что это тоже правильно:

SOCKET s; 
struct sockaddr_in server, si_other; 
int slen, recv_len; 
char buf[10]; 
WSADATA wsa; 

slen = sizeof(si_other); 

//Initialise winsock 
printf("\nInitialising Winsock..."); 
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) 
{ 
    printf("Failed. Error Code : %d", WSAGetLastError()); 
    exit(EXIT_FAILURE); 
} 
printf("Initialised.\n"); 

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

//Prepare the sockaddr_in structure 
server.sin_family = AF_INET; 
server.sin_addr.s_addr = INADDR_ANY; 
server.sin_port = htons(14996); 

//Bind 
if (::bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) 
{ 
    printf("Bind failed with error code : %d", WSAGetLastError()); 
    exit(EXIT_FAILURE); 
} 
puts("Bind done"); 

//blocking on it, waiting for data 
if ((recv_len = recvfrom(s, buf, 10, 0, (struct sockaddr *) &si_other, &slen)) == SOCKET_ERROR) 
{ 
    printf("recvfrom() failed with error code : %d", WSAGetLastError()); 
    exit(EXIT_FAILURE); 
} 

//print details of the client/peer and the data received 
printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port)); 
printf("Data: %s\n", buf); 

Некоторые описания, которые могут помочь - основной цикл сервера выберите(), и когда клиент попросить того, сервер отправить заказ обратно клиенту и начинает команду продолжить.

server: 
while (1) { 
    select() 

     if (socket is in FD_SET) 
      get data, send it back and handleCommand() 
} 

handleCommand() { 
    tcp data exchange 
    wait for udp packet - it fail 
} 

client: 

sendCommand() 

//another receiving commands thread 
while (recv) { 
    handle command 
    tcp data exchange 
    send udp data 
} 

Pls не дает мне сообщений, чтобы сделать это в другом режиме ожидания. Мне нужно пробить отверстие для NAT Traversal. Какая проблема? Другой слушатель, хватающий мои данные? Но netstat -nop UDP -a не давал информации о том, что что-то другое слушает, а привязка сокета не сработала. Также другая важная информация Этот код работает в начале программы, я имею в виду серверные данные, но позже нет.

+0

Вы уверены, что настроили гнездо UDP-сервера _before_, вы отправляете данные? Это не ясно в вашем вопросе. – ElderBug

+0

* Предупреждение * Ваша переменная 'message' может быть неправильно инициализирована:' memcpy (message, "cokolwiek", 8); ', проверить значение, возвращаемое' strlen() ' – purplepsycho

+0

@ElderBug да, в этом была проблема, спасибо приятель. Но почему данные не пришли к recvbuffer? – colorgreen

ответ

1

Окей, так ElderBug сказал

Вы уверены, что вы установили сервер сокета UDP, прежде чем отправить данные? В вашем вопросе неясно

Да, это была моя ошибка. Минисекунды решили, что отправка данных на один компьютер была выполнена до настройки слушателя на сервере. Спасибо за ответ.

Но я точно не понимаю проблему. Должен ли этот доход данных получать буфер и ждать «захвата» его функцией recvfrom?

+0

Прежде чем настроить сокет, ОС получит пакет, но для порта не будет соответствующего сокета, поэтому пакет будет просто отброшен. Это имеет смысл, если вы принимаете это по-другому: было бы странно, дороже (и потенциально опасно) хранить каждый случайный пакет независимо от прослушивающих сокетов. – ElderBug

+0

Да, это правильно! Спасибо за объяснение! – colorgreen