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> 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> 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;
}
}
3 Réponses :
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. P>
Alors, essayez de commenter ConnectToHost et utilisez directement Writetagram lors de l'envoi. P>
Je suis d'accord. Connect n'a pas beaucoup de sens sur UDP. Une certaine implémentation ne parvient pas à code> Recvrom code> si vous n'avez rien envoyé, vous pouvez donc SENDTO code> n'importe quoi à n'importe où ... Qu'en est-il d'essayer un récepteur UDP de base, par exemple
netcat code>.
Essayez avec NC et vérifiez les paquets recevant de FPGA
nc -lu 192.168.10.10 1920
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
Le paquet semble ne pas être un datagramme UDP valide.
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 POST original strong>: p> au lieu de vos données actuelles, vous devez envoyer comme celui-ci pour avoir un datagramme valide: p> 0a9f....
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!
Les paquets UDP souhaités sont-ils effectivement envoyés de
192.168.10.200:1920 code> à
192.168.10.10:1919 code>? Pouvez-vous montrer les informations réelles du paquet UDP de Wireshark? Recevez-vous les paquets si vous supprimez l'appel sur
ConnectToHost () code>?
@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 () code> est hors de propos lors de l'utilisation de
lishagram () code>. L'écriture doit être effectuée à l'aide de
Writetagram () Code>. Si vous utilisez
ConnectTohos () Code> dans le mode natif (
qiodevice (code>), vous devez également utiliser le
correspondant () code> et
écrire (code> écrire ( ) code>.
Readyread () Code> 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.