2017-06-30 1 views
0

Je suis en train de lire ces paquets UDP entrants en utilisant Wireshark:Essayer de recevoir des paquets UDP entrants, le tampon vide

Wireshark

J'utilise le code suivant:

struct sockaddr_in si_other; 
struct sockaddr_in remaddr;  /* remote address */ 
int slen = sizeof(remaddr); 

int s, recvlen; 
char buf[BUFLEN]; 
char message[BUFLEN]; 
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, 0)) == SOCKET_ERROR) //IPPROTO_UDP 
{ 
    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(PORT); 
si_other.sin_addr.S_un.S_addr = inet_addr(SERVER); 

if (bind(s, (struct sockaddr *)&si_other, sizeof(si_other)) < 0) { 
    perror("bind failed"); 
    return 0; 
} 

u_long nMode = 1; // 1: NON-BLOCKING 
if (ioctlsocket(s, FIONBIO, &nMode) == SOCKET_ERROR) 
{ 
    closesocket(s); 
    WSACleanup(); 
    return 0; 
} 
//start communication 
while (1) 
{ 

    printf("waiting on port %d\n", PORT); 

    if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == SOCKET_ERROR) 
    { 
     printf("recvfrom() failed with error code : %d", WSAGetLastError()); 
     exit(EXIT_FAILURE); 
    } 

    printf("Done"); 
    puts(buf); 
} 

Le adresse que je lie est 192.168.1.1 et le port 1234.

Et la sortie donnée par WSAGetLastError est une erreur de mémoire tampon vide: 10035

J'ai essayé de déconnecter le mur à l'épreuve du feu, l'antivirus ... et j'exécute le programme en tant qu'administrateur, et cela n'a pas aidé.

Pourquoi le tampon est-il vide? Je vois clairement qu'il y a des paquets qui arrivent, qu'est-ce qui pourrait bloquer les données entrantes à la socket?

+1

Pourquoi ne pas bloquer? – Jonas

+0

Parce qu'avec non-bloquant je suis capable de lire l'erreur et de voir que le tampon est vide, sinon le programme s'arrête sur la fonction recvfrom ... – joe

+1

Mais s'il n'est pas bloquant l'appel pourrait retourner simplement parce qu'il n'y a pas de données disponible pour le moment. Quelle est l'erreur - 'EAGAIN' ou' EWOULDBLOCK'? –

Répondre

0

the given output by WSAGetLastError() is an empty buffer error: 10035

Non, ce n'est pas le cas. 10035 est WSAEWOULDBLOCK. Cela signifie que l'opération bloquerait en mode de blocage, c'est-à-dire qu'aucune donnée n'était présente pour être reçue au moment où vous avez appelé recvfrom().

The address I'm binding is 192.168.1.1

The IP 192.168.1.1 is shown as a gateway

Ces deux instructions sont mutuellement incohérentes. S'il s'agit d'une passerelle, il s'agit d'une adresse IP externe, et s'il s'agit d'une adresse IP externe, vous ne pouvez pas vous lier à celle-ci.

I tried INADDR_ANY and it didn't help

Pas étonnant. Si vous n'êtes pas 192.168.1.1, vous ne pouvez pas recevoir ses messages. Pas clair pourquoi vous penseriez autrement.

+0

Ok, maintenant j'ai plus de points de remerciement. .. – joe

0

Comme @EJP mentionné 10035 est WSAEWOULDBLOCK, c'est-à-dire qu'aucune donnée n'est prête. La cause de ceci est que le récepteur est 192.168.1.1 qui est l'adresse IP de votre passerelle, donc pas une adresse IP locale. Dans ce cas, vous ne pouvez pas recevoir les paquets normalement.

Vous pouvez recevoir ces paquets, même s'ils ne vous sont pas destinés, en utilisant un renifleur UDP, par exemple en utilisant libpcap.

+0

Un grand merci Jonas qui clarifie pourquoi je ne peux pas recevoir ces paquets.Merci pour le lien, je vais jeter un coup d'oeil. – joe

+0

@joe Vous êtes le bienvenu. Faites-moi savoir si vous avez besoin d'aide supplémentaire, par exemple, en utilisant libpcap ou en écrivant votre propre fonction de capture de paquets. S'il vous plaît accepter (et éventuellement upvote) une réponse si elle résout votre problème. – Jonas

-1

Merci pour les réponses, ils m'ont indiqué la bonne direction. J'ai maintenant le programme qui fonctionne et je suis en mesure de recevoir les paquets UDP entrants.

La solution était de « renifler » ces paquets UDP, Winsock permet que l'utilisation de la fonction de WSAIoctl après bind, dans mon cas, en ajoutant le code suivant au programme ci-dessus (après la fonction de liaison):

if (WSAIoctl(s, SIO_RCVALL, &j, sizeof(j), 0, 0, (LPDWORD)&si_other, 0, 0) == SOCKET_ERROR) 
{ 
    printf("WSAIoctl() failed.\n"); 
    return 1; 
} 

J'espère pouvoir aider quelqu'un d'autre avec un problème similaire.

+0

La solution consistait à ne pas lier à une adresse IP externe. Et le mot est des paquets, pas des paquets. – EJP