0
votes

I want to send/receive data from a device via UDP. The device acts as a server and if I send it a value it sends me some values back. First I write a little python code which works without any problems:

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

I can write a value to a register with this script and get an array with all updated register values from the device back. I write an equal program 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 Address 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);
    }   
}

I am able to sent values and the device sends its register values back so the communication works (I checked this with wireshark). But I can't receive the data in my program. I oncomment the recv function because the program gets stuck at this point if I want to receive. The recvfrom() function doesn't work at this point too. I tried the bind() function instead of connect because in the python script it works with sock.bind. But than I cant send or receive. I was reading several posts about UDP receive function but can't find my mistake. Can someone help me?

1
Some error handing would have been useful in your situation - rustyx
Who is sending the response back to your C code? Do you expect to receive the packet you have sent using your C code? - Daniel Trugman
@Daniel According to the OP, it is a device which lives at IP address 192.168.42.33 (the comment says "scanner unit"). And no, he doesn't expect to receive the packet he has sent, he expects to receive a response from the device. - Martin Bonner supports Monica
What is the return value from send (and socket and connect)? - Martin Bonner supports Monica

1 Answers

0
votes

The Python code binds to all existing local interfaces at port 5004, whereas the C code will implicitly bind to a local free port during the call to connect(), thus if the remote peer is hard-coded to respond to port 5004, the socket will not receive it.

You should add a call to bind() right after creating your socket:

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

And see what happens :)