Я пишу программное обеспечение C для взаимодействия с контроллером мотора через UDP. Я использую:C оконная розетка навсегда заблокирована при первом выполнении
- Win 7 Pro 64-Bit
- затмение Луна
- MinGW
На данный момент у меня есть проблема, которая, кажется, гнездо/WSA, связанные с: выполнение моей программы застряло на recvfrom() навсегда (очевидно, что контроллер не отвечает так, как ожидалось). С прилагаемым программным обеспечением это происходит только при первом выполнении (или после того, как оно не выполняется в течение примерно 3 минут), другие программы имели эту проблему 3-4 раза подряд. Взгляд в wirehark показал, что первая (или после 3мин паузы) приводит к передаче пакета «ARP» вместо моего сообщения UDP. Почему это (кажется, ищет место назначения)? Как я могу избежать «срыва» моего программного обеспечения из-за этого?
Неужели я забыл инициализировать что-нибудь?
Мой код выглядит следующим образом:
#include <stdio.h>
#include <conio.h>
#include <winsock2.h>
#define Y_AXIS_IP "XXX.XXX.XXX.XX"
#define Y_AXIS_PORT 880X
int startWinsock(void);
int main() {
//Start the winsocket (needed to create sockets)
long ws = startWinsock();
if (ws) {
printf("ERROR: Failed to init Winsock API! Code: %ld\n", ws);
getch();
exit(EXIT_FAILURE);
}
//Create an UDP Socket
SOCKET UDPsocket = socket(AF_INET, SOCK_DGRAM, 0);
if (UDPsocket == INVALID_SOCKET) {
printf("ERROR: Socket could not be created! Code: %d\n",
WSAGetLastError());
getch();
exit(EXIT_FAILURE);
}
//Create a struct to use with the socket (this gives information about type (AF_INET = Internet Protocol) which port and which IP to use)
SOCKADDR_IN addrY;
memset(&addrY, 0, sizeof(addrY));
addrY.sin_family = AF_INET; //Assert Type
addrY.sin_port = htons(Y_AXIS_PORT); //Assert Port
addrY.sin_addr.S_un.S_addr = inet_addr(Y_AXIS_IP); //assert IP Address
char message[] = "0000MTX 00000000OR:1:000F\r";
int buffersize = 100;
char *recvbuf = malloc(buffersize); //None of the replys can get larger than 100 chars
if (recvbuf == NULL) {
printf("Out of memory!\n");
getch();
exit(EXIT_FAILURE);
}
//clear the receive buffer and prepare the address size
memset(recvbuf, '\0', buffersize);
int addrsize = sizeof(addrY);
//Send the message to the device
if (sendto(UDPsocket, message, strlen(message), 0,
(struct sockaddr *) &addrY, sizeof(addrY)) == SOCKET_ERROR) {
printf("sendto() failed with error code : %d", WSAGetLastError());
getch();
exit(EXIT_FAILURE);
}
//Receive from device (blocks program until recv event)
if (recvfrom(UDPsocket, recvbuf, buffersize, 0, (struct sockaddr *) &addrY,
&addrsize) == SOCKET_ERROR) {
//If not timed out Display the Error
printf("recvfrom() failed with error code : %d", WSAGetLastError());
getch();
exit(EXIT_FAILURE);
}
printf("%s\n", recvbuf);
getch();
free(recvbuf);
return 0;
}
int startWinsock(void) {
WSADATA wsa;
return WSAStartup(MAKEWORD(2, 2), &wsa);
}
Я был бы очень счастлив, если бы вы имели какие-либо идеи или предложения. Заранее большое спасибо!
Это полностью звучит как проблема ARP. Читайте о ARP. Вам нужно обработать случай, когда ARP приведет к отказу первого пакета после некоторого времени простоя. – ElderBug