У меня проблема, потому что мой сервер не получает данные UDP. Порты на маршрутизаторе пересылаются, данные поступают в сеть локального сервера (это видно на сниффере (3)), но сервер их не получает.
Вы можете видеть, что 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);
Некоторое описание, которое может помочь — основной цикл сервера — это select (), и когда клиент запрашивает заказ, сервер отправляет заказ обратно клиенту и начинает выполнение команды.
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
}
Просьба не дать мне ответы, чтобы сделать это в другое ожидание. Мне нужно пробить дыру в NAT Traversal. Что это за проблема? Другой слушатель захватывает мои данные? Но netstat -nop UDP -a не дал информацию о том, что что-то другое слушает, и связывание сокета не завершилось неудачей. Также другая важная информация Этот код работает в начале программы, я имею в виду сервер получает данные но позже нет.
Хорошо, так как ElderBug сказал
Вы уверены, что настроили сокет UDP-сервера перед отправкой данных? Непонятно в твоем вопросе
Да, это была моя вина. За считанные секунды было решено, что отправка данных на одном компьютере была выполнена до настройки прослушивателя на сервере. Спасибо за ответ.
Но я не совсем понимаю проблему. Разве эти данные не должны получать буфер и ждать, пока он не «захватит» его функцией recvfrom?
Других решений пока нет …