2017-09-20 4 views
0

Je souhaite envoyer/recevoir des données d'un périphérique via UDP. L'appareil agit comme un serveur et si je lui envoie une valeur, il m'en renvoie des valeurs. D'abord, je vous écris un petit code python Wich fonctionne sans prolems:UDP C++ receive

import socket 
import time 

UDP_IP = "192.168.42.33" 
UDP_PORT = 5004  

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
sock.bind(('',UDP_PORT)) 

while True: 
    MESSAGE = input('Write new message: ') 
    sock.sendto(bytes.fromhex(MESSAGE), (UDP_IP, UDP_PORT)) 
    time.sleep(0.1) 
    data, addr = sock.recvfrom(1076) 

    a = len(data) 
    print ("Byte: ", data.hex()[46], data.hex()[47]) 

Je peux écrire une valeur à un registre avec ce script et obtenir un tableau avec toutes les valeurs de registre mises à jour de l'appareil arrière. Je vous écris un programme d'égalité en C++:

#pragma once 
#pragma comment(lib, "Ws2_32.lib") 

#include <sdkddkver.h> 
#include <WinSock2.h> 
#include <Windows.h> 
#include <iostream> 
#include <string> 

#define SCK_VERSION2 0x0202 
#define BUFLEN 2048 
using namespace std; 

int main() 
{ 
    int inputI;    
    long SUCCESSFUL; 
    WSAData WinSockData;   
    WORD DLLVersion; 
    SOCKET sock; 
    char msg_input[] = { 0x60, 0x01, 0x00, 0x00}; //Write REG mode, 1 byte 
    char* SU_IP = "192.168.42.33"; //IP Adress of Scanner Unit 
    u_short SU_PORT = 5004;   //Port of Scanner Unit 
    SOCKADDR_IN ADDRESS; 
    char buf[BUFLEN]; 
    int slen = sizeof(ADDRESS); 

    DLLVersion = MAKEWORD(2, 1); 
    SUCCESSFUL = WSAStartup(DLLVersion, &WinSockData); 

    sock = socket(AF_INET, SOCK_DGRAM, 0); 
    ADDRESS.sin_addr.s_addr = inet_addr(SU_IP); 
    ADDRESS.sin_family = AF_INET; 
    ADDRESS.sin_port = htons(SU_PORT); 

    connect(sock, (SOCKADDR*)&ADDRESS, sizeof(ADDRESS)); 

    while (1) 
    { 
     cout << "Adresse des Registers (hex): "; 
     cin >> hex >> inputI; 
     msg_input[2] = inputI; 
     cout << "Wert des Registers (hex): "; 
     cin >> hex >> inputI; 
     msg_input[3] = inputI; 
     send(sock, msg_input, sizeof(msg_input), NULL); 
     //recv(sock, buf, BUFLEN, 0); 
    } 
} 

Je suis en mesure de valeurs envoyées et l'appareil envoie ses valeurs de registre de retour de sorte que les travaux de communication (j'ai vérifié cela avec Wireshark). Mais je ne peux pas recevoir les données dans mon programme. Je surcomment la fonction recv parce que le programme se bloque à ce point si je veux recevoir. La fonction recvfrom() ne fonctionne pas à ce stade aussi. J'ai essayé la fonction bind() au lieu de se connecter car dans le script python cela fonctionne avec sock.bind. Mais que je ne peux pas envoyer ou recevoir. Je lisais plusieurs articles sur la fonction de réception UDP mais je ne trouve pas mon erreur. Est-ce que quelqu'un peut m'aider?

salutations Tobias

+4

Certains remise d'erreur aurait été utile dans votre situation – rustyx

+0

qui envoie la réponse à votre code C? Pensez-vous recevoir le paquet que vous avez envoyé en utilisant votre code C? –

+0

@Daniel Selon l'OP, il s'agit d'un périphérique qui réside à l'adresse IP 192.168.42.33 (le commentaire dit "unité de scanner"). Et non, il ne s'attend pas à recevoir le paquet qu'il a envoyé, il s'attend à recevoir une réponse de l'appareil. –

Répondre

0

Le code python se lie à toutes les interfaces locales existantes au port 5004, alors que le code C se lie implicitement à un port libre locale lors de l'appel à la connexion(), donc si le poste distant est codé en dur pour répondre au port 5004, le socket ne le recevra pas.

Vous devez ajouter un appel à lier() juste après la création de votre prise:

bind(sock, (sockaddr *)&ADDRESS, sizeof(ADDRESS)); 

Et voir ce qui se passe :)

+0

Merci pour votre réponse. J'ai utilisé la fonction bind() et ajouté une erreur de handlich comme dit Jean-Bernard Jansen. Je reçois le code d'erreur 10049 lorsque je lie le socket, ce qui signifie que l'adresse n'est pas disponible. Mais l'adresse doit être disponible. – Widde

+0

Une vérification rapide dans [MSDN] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668 (v = vs.85) .aspx) montre que cette erreur signifie que vous essayez de lier le socket à "une adresse qui n'est pas valide pour l'ordinateur local". Exécutez 'ipconfig' sous une invite de commande et vérifiez quelles adresses IP sont allouées pour vos interfaces réseau. –

+0

'ADDRESS.sin_addr.s_addr' est défini sur l'adresse IP du périphérique lors de l'appel' connect() '. Le client ne peut pas 'bind()' à cette adresse IP. Assurez-vous de régler 'ADDRESS.sin_addr.s_addr' sur' INADDR_ANY' (si ce n'est pas une adresse IP locale spécifique) en appelant 'bind()' avant 'connect()'. –