6
votes

Datagrammes Vu dans Wireshark, non reçu par QT UDP Socket

J'écris une application QT (5.6) qui communique avec une prise FPGA sur UDP. Les paquets sont en ruine sur le PC à 2 kHz (toutes les paquets de taille identique, 1272 octets). Wireshark montre que des paquets sont envoyés et que l'en-tête UDP est comme prévu. Le problème est que la prise QT UDP que j'utilise ne reçoit jamais ces paquets. Le signal Lisyyead strud> n'est jamais appelé.

Voici un extrait de code: P>

UdpConnection::UdpConnection(QObject* parent)
{
    fpgaConnection = QSharedPointer<QUdpSocket>(new QUdpSocket);

    qDebug() << connect(fpgaConnection.data(), &QUdpSocket::readyRead, this, &UdpConnection::readyRead);

    if (fpgaConnection->bind(QHostAddress("192.168.10.10"), 1920))
    {
        qDebug() << "Successfully Bound!";
    }
    else
    {
        qDebug() << "BINDING FAILURE";
    }

    fpgaConnection->connectToHost(QHostAddress("192.168.10.200"), 1919);

    sendArpRequest();
}

void UdpConnection::readyRead()
{
    while (fpgaConnection->hasPendingDatagrams())
    {
        QByteArray buffer;
        buffer.resize(fpgaConnection->pendingDatagramSize());

        QHostAddress sender;
        quint16 senderPort;

        fpgaConnection->readDatagram(buffer.data(), buffer.size(), &sender, &senderPort);
        qDebug() << "Message from:" << sender;
        qDebug() << "Message port:" << senderPort;
        qDebug() << buffer;
    }
}
  • UDPConnection ne fonctionne pas sur un fil séparé de la principale. Devrait-il être? Li>
  • Je suis contraignant avec succès et je supposerais que "ConnectToHost" fonctionne car je suis capable d'envoyer un message à l'hôte distant. Li>
  • L'application a été ajoutée à la liste d'exceptions du pare-feu (à nouveau, la poignée de main ARP prouve qu'elles sont capables de communiquer). Li>
  • L'interface est une connexion Ethernet directe entre la FPGA et un PC. LI> ul>

    Pourquoi WireShark est-il capable de voir ces messages, mais mon programme n'est pas? p>

    Mise à jour # 1 strong> Wireshark a les paquets de 2 kHz en tant que paquets LLC. L'en-tête Ethernet affiche une destination correcte (mon adresse MAC), adresse source (codé dur dans la FPGA) et la longueur. L'en-tête IP a la source IP Source en 192.168.10.200 et l'IP de destination en 192.168.10.10. L'en-tête UDP a un port source en tant que port de 1920 et de destination comme 1919. P>

    Mise à jour # 2 strong> Logs Wireshark: Pâte.ee/98C1H Comme vous pouvez le constater, le paquet est répété et envoyé de la FPGA à 2KHz. La transmission et la réponse de l'ARP peuvent être trouvées comme le 5ème, 10ème et 11ème paquet. P>

    Mise à jour # 3 forte> Les paquets IP des paquets entrants ont une somme de contrôle correcte qui n'est pas définie sur 0x0000. P> p>


18 commentaires

Les paquets UDP souhaités sont-ils effectivement envoyés de 192.168.10.200:1920 à 192.168.10.10:1919 ? Pouvez-vous montrer les informations réelles du paquet UDP de Wireshark? Recevez-vous les paquets si vous supprimez l'appel sur ConnectToHost () ?


@RemyleBeau ajouté dans la mise à jour n ° 1


@RemyleBeau Je reçois les paquets dans Wireshark si je lance la demande ou non. Dès que j'allume le FPGA, ils se présentent dans Wireshark et commencent à transmettre immédiatement.


Il est difficile de vous aider sans voir les données Wireshark. Mais un commentaire: Le fait que ARP fonctionne ne signifie pas que le pare-feu est bien configuré. En fait, si ce que vous dites est correct, une possibilité réelle est que le pare-feu tombe sur le datagramme. Ou peut-être que le datagramme est supprimé pour une autre raison. Vous devriez également montrer aux IPTABLES.


@rodolk que les données Wireshark seraient spécifiquement utiles?


@Mattdavben essentiellement celui qui affiche tous les messages UDP dans les messages de direction et d'ARP. Wireshark créera un fichier avec tout le trafic.


@rodolk Wireshark Journaux: Pâte.ee/98C1H Vous pouvez le constater, le paquet est répété et envoyé de la FPGA à 2KHz. La transmission et la réponse de l'ARP se trouvent comme le 5ème, 10ème et 11ème paquet.


Il convient de noter que la somme de contrôle est codée dur à 0x0000 (car nous utilisons IPv4, la somme de contrôle est ignorée) et le champ d'identification est correctement itération.


Si vous remplacez le premier argument à la liaison () avec Qhostaddress :: Anyipv4 et / ou commenter l'appel de ConnectToHost (), cela fait-il une différence?


De plus, le dernier argument de votre Connect () n'aurait-il pas dû être et udpconnection :: Readyead à la place de & fpga_hardwareinterface :: Readyread?


@Jeremyfriesner: Je l'ai essayé avec TheNipv4, pas de dés. Il dit que j'ai tenu avec succès à 0.0.0.0, mais pas 192.168.10.10.10. En outre, c'était une faute de frappe pour référence FPGA_HARDWAREINTORFACE (c'est le vrai nom de ma classe). Il a été corrigé.


Étant donné que UDP est une sorte de commuication sans connexion, ConnectToHost () est hors de propos lors de l'utilisation de lishagram () . L'écriture doit être effectuée à l'aide de Writetagram () . Si vous utilisez ConnectTohos () dans le mode natif ( qiodevice ), vous devez également utiliser le correspondant () et écrire (code> écrire ( ) . Readyread () devrait-il être valide. Êtes-vous sûr que ce n'est pas appelé et ne fournit simplement pas de datagramme? De plus, vous ne devez-vous pas arriver pour que cela soit réellement séparé dans plusieurs threads?


@Sebastianlange Je suis écoutant le 192.168.10.10.10:1920 et écrivant au 192.168.10.200:1919, donc je suis lié à un et connecté à l'autre. Devrais-je être contraignant pour les deux, puis utiliser ReadDatagram et Writetagram? Parce que maintenant, je suis capable de connecter avec succès () et d'écrire () sur le port distant, je ne peux tout simplement pas recevoir sur le port d'écoute.


Le colis que vous recevez n'est tout simplement pas un datagramme autant que je sache. Votre taille dans l'en-tête Ethernet doit être le type IPv4 suivi de la trame IP suivie de l'en-tête UDP et de votre charge utile. Étant donné que la prise UDP tente d'interpréter les datagrammes complets, il ne vous donne aucun signal pour lire maintenant un nouveau datagramme.


@Sebastianlange au lieu du type IPv4 (0x800 pour UDP), nous utilisons la longueur du paquet. J'ai supposé que c'était valide, car il était inférieur à 1500 (qui signifie typiquement la longueur au lieu de type). Pensez-vous que si nous avons changé cela à 0x800, ils peuvent être interprétés comme des datagrammes UDP?


Essayé fidéliser un datagramme UDP semi-valide comme une réponse rapidement ...


@Sebastianlange plaine et simple: ce comportement pourrait-il venir d'utiliser la longueur de l'image plutôt que l'étherType?


Fait amusant, ça fait. Il montre en fait un package UDP valide sur la première vue.


3 Réponses :


2
votes

Je ne suis pas trop familier avec Qt, mais pour l'API de socket BSD, j'utilise généralement Lié pour définir mon port de réception, mais n'utilisez pas de connexion pour la connexion UDP, notamment lorsque vous utilisez différents ports tels que votre 1919 VS 1920 Pour l'API de socket, utilisez SendTo () pour envoyer des paquets avec l'IP / Port cible.

Alors, essayez de commenter ConnectToHost et utilisez directement Writetagram lors de l'envoi.


1 commentaires

Je suis d'accord. Connect n'a pas beaucoup de sens sur UDP. Une certaine implémentation ne parvient pas à Recvrom si vous n'avez rien envoyé, vous pouvez donc SENDTO n'importe quoi à n'importe où ... Qu'en est-il d'essayer un récepteur UDP de base, par exemple netcat .



0
votes

Essayez avec NC et vérifiez les paquets recevant de FPGA

nc -lu 192.168.10.10 1920


5 commentaires

Il semble que Netcat ne reçoit rien. J'ai dû utiliser "Lup" comme les drapeaux parce qu'il s'agit d'un port UDP. Cela signifie-t-il que la carte réseau ou le système d'exploitation dépose les paquets?


-P est utilisé pour spécifier le port source des paquets à venir, vous devez simplement utiliser -lu pour recevoir des paquets UDP à partir du réseau.


Aussi, veuillez vérifier qu'il n'y a pas d'ICMP "inaccessible" ou d'autres paquets d'erreur ICMP de votre ordinateur au FPGA. Peut-être que le système d'exploitation informer l'expéditeur pourquoi il a chuté un paquet.


Pas de paquets ICMP sortant. Netcat ne me laissera pas utiliser "LU" (je reçois l'erreur "UDP Ecouter Besoins -P ARG"). "Lup" et "LP" ne produisent rien.


@Mattdavben lookat serverfault.com/questions/207683/... Test avec NC -LL 1920



1
votes

Le paquet semble ne pas être un datagramme UDP valide.

EDIT STRY>: P>

Après avoir créé le paquet, il semble suffire de changer le type dans l'Ethernet en-tête vers IPv4 (0x0800). P>

Il montre une étrange ttl forte> avec une valeur de 0, mais qui peut être lié à l'expéditeur. P>

POST original strong>: p>

au lieu de vos données actuelles, vous devez envoyer comme celui-ci pour avoir un datagramme valide: p>

en-têtes Ethernet avec IPv4 strong> (14byte): (comme dans votre Mise en œuvre, mais type IPv4 0x0800), Source, Dest, Type P>

0a9f....


2 commentaires

Si votre charge utile est de 1246 octets, vous êtes bon avec simplement changer le type de l'en-tête Ethernet, si votre charge utile est de 1270 byes, vous devrez réécrire la génération de paquets.


YEP, s'avère que nous avons changé le champ de cadre Ethernet de la longueur à l'étentype ... Les paquets sont reçus tout à fait. Readyead () et Writedaramgra () fonctionnent simplement bien, je ne me connecte plus à l'hôte, etc. tout solide maintenant. Merci!