2017-09-20 8 views
0

Ich möchte Daten von einem Gerät über UDP senden/empfangen. Das Gerät fungiert als Server und wenn ich ihm einen Wert zusende, schickt er mir einige Werte zurück. Zuerst schreibe ich ein wenig Python-Code weichen Werke ohne prolems:UDP C++ empfange

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]) 

ich einen Wert in ein Register mit diesem Skript schreiben und einen Array mit allen aktualisierten Registerwerten aus dem Gerät zurück. Ich schreibe ein gleiches Programm in 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); 
    } 
} 

ich gesendeten Werten der Lage bin, und das Gerät sendet seine Registerwert zurück, so dass die Kommunikation funktioniert (Ich habe dies mit wireshark). Aber ich kann die Daten in meinem Programm nicht empfangen. Ich empfehle die Recv-Funktion, weil das Programm an diesem Punkt hängenbleibt, wenn ich empfangen möchte. Die Funktion recvfrom() funktioniert auch an dieser Stelle nicht. Ich habe versucht, die bind() - Funktion anstelle von connect, weil im Python-Skript mit sock.bind funktioniert. Aber als ich nicht senden oder empfangen kann. Ich habe mehrere Posts über die UDP-Empfangsfunktion gelesen, kann aber meinen Fehler nicht finden. Kann mir jemand helfen?

Grüße Tobias

+4

Einige Fehler Gabe in Ihrer Situation nützlich gewesen wäre – rustyx

+0

Wer sendet Antwort zurück zu Ihrem C-Code? Erwarten Sie, dass Sie das Paket erhalten, das Sie mit Ihrem C-Code gesendet haben? –

+0

@Daniel Laut dem OP ist es ein Gerät, das unter der IP-Adresse 192.168.42.33 lebt (der Kommentar sagt "Scanner-Einheit"). Und nein, er erwartet nicht, das Paket, das er gesendet hat, zu erhalten, er erwartet eine Antwort von dem Gerät zu erhalten. –

Antwort

0

Der Python Code bindet an alle vorhandenen lokalen Schnittstellen-Port 5004, während der C-Code implizit zu einem lokalen freien Port während des Anrufs binden wird() zu verbinden, so dass, wenn die Gegenstelle ist hart-codiert, um auf Port 5004 zu antworten, wird der Socket es nicht empfangen.

Sie einen Anruf hinzufügen sollten binden() direkt nach dem Sockel zu schaffen:

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

Und sehen, was passiert :)

+0

Danke für Ihre Antwort. Ich benutzte die bind() Funktion und fügte Fehler handlich wie Jean-Bernard Jansen hinzu. Ich bekomme den Fehlercode 10049, wenn ich den Socket binde, was bedeutet, dass die Adresse nicht verfügbar ist. Aber die Adresse muss verfügbar sein. – Widde

+0

Ein schneller Check-in [MSDN] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668 (v = vs.85) .aspx) zeigt, dass dieser Fehler bedeutet, dass Sie versuchen Binden Sie den Socket an "eine Adresse, die für den lokalen Computer nicht gültig ist". Führen Sie 'ipconfig' unter einer Eingabeaufforderung aus und überprüfen Sie, welche IP-Adressen für Ihre Netzwerkschnittstellen zugewiesen sind. –

+0

'ADDRESS.sin_addr.s_addr' wird beim Aufruf von' connect() 'auf die IP des Geräts gesetzt. Der Client kann nicht an diese IP-Adresse binden(). Achten Sie darauf, 'ADDRESS.sin_addr.s_addr' auf' INADDR_ANY' zu setzen (wenn nicht auf eine bestimmte lokale IP), wenn Sie 'bind()' vor 'connect()' aufrufen. –