Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

UDP receive problem via SysSocket [CODESYS Control Win V3.5]

dino
2021-07-08
2021-07-08
  • dino - 2021-07-08

    Hi, I try to send and receive data using a UDP connection via SysSocket 3.5.17.0. While sending data works fine, I have problems with the receiving part.

    Basically, the code looks like this:

    PROGRAM UdpTest
    VAR
        test_string : STRING(25) := 'Test string';
    
        socket_handle : RTS_IEC_HANDLE;
        socket_address : SOCKADDRESS;
        sys_result : RTS_IEC_RESULT;
        enable_option : DINT := 1;
    
        bytes_sent : __XINT;
        bytes_received : __XINT;
        bytes_available : DINT;
    
        receive_buffer : ARRAY [0..63] OF BYTE;
        udp_reply : UDP_REPLY2;
    END_VAR
    
    socket_address.sin_family := SOCKET_AF_INET;
    socket_address.sin_port := SysSockHtons(12000);
    socket_address.sin_addr.ulAddr := SysSockHtonl(SOCKET_INADDR_ANY);
    
    socket_handle := SysSockCreate(socket_address.sin_family, SOCKET_DGRAM, SOCKET_IPPROTO_UDP, ADR(sys_result));
    
    sys_result := SysSockSetOption(socket_handle, SOCKET_SOL, SOCKET_SO_REUSEADDR, ADR(enable_option), SIZEOF(enable_option));
    
    sys_result := SysSockBind(socket_handle, ADR(socket_address), SIZEOF(socket_address));
    

    (For better readability, checking of the return values is omitted.)

    The sending part is working well:

    bytes_sent := SysSockSendToUdp(socket_handle, 12010, '127.0.0.1', ADR(test_string), SIZEOF(test_string), ADR(sys_result));
    

    However, I am not able to receive any data:

    bytes_received := SysSockGetRecvSizeUdp(socket_handle, 0, ADR(sys_result));
    

    always yields 0.

    sys_result := SysSockIoctl(socket_handle, SOCKET_FIONREAD, ADR(bytes_available));
    

    also yields 0 for bytes_available all the time.

    Therefore, I made the socket non-blocking:

    sys_result := SysSockIoctl(socket_handle, SOCKET_FIONBIO, ADR(enable_option));
    

    and tried to receive the data:

    bytes_received := SysSockRecvFromUdp2(socket_handle, ADR(receive_buffer), SIZEOF(receive_buffer), ADR(udp_reply), ADR(sys_result));
    

    I also tried

    bytes_received := SysSockRecvFrom(socket_handle, ADR(receive_buffer), SIZEOF(receive_buffer), 0, ADR(socket_address), SIZEOF(socket_address), ADR(sys_result));
    

    with variations of socket_address, but unfortunately without success.

    Only when I use

    socket_handle := SysSockCreateUdp(12000, 12000, ADR(sys_result));
    

    checking the RecvSize gave me a value different from 0:

    bytes_received := SysSockGetRecvSizeUdp(socket_handle, 0, ADR(sys_result));
    

    However, for this setup I have to change the port every time I start the application, even though SOCKET_SO_REUSEADDR is set. Thus, this approach is not satisfactory either.

    What am I doing wrong that prevents the socket created with SysSockCreate from receiving data?

     
  • dino - 2021-07-08

    I just realised that

    bytes_received := SysSockGetRecvSizeUdp(socket_handle, 0, ADR(sys_result));
    

    also works once for each port I specify, i.e. when I define a port, download the application and start it, receiving works. After a restart, bytes_received will remain 0. To make it work again, I need to specify another port or restart the PC.

    Edit:
    It looks like Control Win does not close open ports during a cold restart or application download. Is this intended or a bug? For now, I added a PrepareStop event handler that closes the open port as a workaround.

     

    Last edit: dino 2021-07-09

Log in to post a comment.