Ethernet Gateway DR - Sending but not Receive using Sockets

CAN to LAN gateway in DIN rail plastic casing
Locked
tjlarso
Posts: 4
Joined: Wed 12. Jun 2024, 16:21

Ethernet Gateway DR - Sending but not Receive using Sockets

Post by tjlarso » Wed 12. Jun 2024, 16:38

Hello. I have been working on a project that uses our own C++ implementation using the win32 sockets library for transmitting and receiving messages from a pc to a PCAN-Ethernet Gateway DR. Attached is how I have the device configured to connect to the Gateway.
pcan help.PNG
pcan help.PNG (24.65 KiB) Viewed 2869 times
I set it up to where my laptop is the server, with an IP of "192.168.1.20" on port "5001". The client is the gateway and I am having trouble with the "server.accept()" function where it is waiting for a response from the gateway, but it never comes. Here is the code for that.

Code: Select all

bool CANGateway::connect()
{
    #pragma region server_connect

    SocketServer server;
    server.bind("192.168.1.20", "5001");
    SOCKET clientSock;

    while(true)
    {
        clientSock = server.accept();
        if(clientSock != INVALID_SOCKET)
            break;
    }

    cout << "connected and bound to server" << endl;
    SocketServerConn client(clientSock);

    while(true)
    {
        char val;
        int ret = client.recv(&val, 1, VirtualSocket::WAIT);
        if(ret < 0)
        {
            cout<<"Error receiving data: "<<ret<<endl;
            exit(1);
        }
        else if(ret > 0)
        {
            cout<<"got "<<val<<endl;
            client.send(&val, 1);
            if(val == '\n')
            {
                cout<<"Got end of string!"<<endl;
                break;
            }
        }
        else {/*empty*/}
    }
    #pragma endregion server_connect 

    int ret = _txSock.connect("192.168.1.10", "5000"); //PCAN gateway IP/port
    cout << "_txSock connected status: " << ret << endl;
    
    return ret;
}
My main question is what is the behavior of the gateway supposed to do and how can I get the gateway to send a confirmation back to my server confirming that it is connected so that my accept function can go through. Here is the accept function in my sockets library.

Code: Select all

SOCKET SocketServer::accept()
{

    if(_listenSock == INVALID_SOCKET)
    {
        throw runtime_error("Server not bound!");
    }
    // Accept a client socket
    SOCKET clientSock;

    clientSock = ::accept(_listenSock, NULL, NULL);      // stuck here 

    if(clientSock == INVALID_SOCKET)
    {
        cout << "nothing connected" << endl;
    }

    return clientSock;
}
If you can, please help me with this behavior and if applicable point me in the right direction of which documentation covers this, as I have not been able to find anything. Best and thank you!

M.Heidemann
Sales & Support
Sales & Support
Posts: 1083
Joined: Fri 20. Sep 2019, 13:31

Re: Ethernet Gateway DR - Sending but not Receive using Sockets

Post by M.Heidemann » Thu 13. Jun 2024, 08:40

Hello,

Seems like you are starting from scratch here,
maybe you want to have a look at our example code (C),
which includes both an RX and TX example.
PCAN_Ethernet_Gateway_DR_RXTX_Sample.zip
(10.45 KiB) Downloaded 1897 times

Best Regards

Marvin
---
Marvin Heidemann
PEAK-Support Team

tjlarso
Posts: 4
Joined: Wed 12. Jun 2024, 16:21

Re: Ethernet Gateway DR - Sending but not Receive using Sockets

Post by tjlarso » Thu 13. Jun 2024, 15:16

Thank you Marvin! I have had the chance to review that code previously, and it has not really guided me in the direction I would like to be in yet.

Alternatively, after looking through more documentation I decided to go into my poi_config for the gateway and for my [rt_1] which is CAN2LAN, I made "invert_socket_mode" true instead of the default of false. This is in hopes that I can get a message back from the gateway in a client -> client manner with no server implimentation needed, which might end up being more simple.

Code: Select all

bool CANGateway::connect()
{

    #pragma region server_connect // it is commented out


    /*
    SocketServer server;
    server.bind("192.168.1.20", "5001");
    SOCKET clientSock;

    while(true)
    {
        clientSock = server.accept();
        if(clientSock != INVALID_SOCKET)
            break;
    }

    cout << "connected and bound to server" << endl;
    SocketServerConn client(clientSock);

    while(true)
    {
        char val;
        int ret = client.recv(&val, 1, VirtualSocket::WAIT);
        if(ret < 0)
        {
            cout<<"Error receiving data: "<<ret<<endl;
            exit(1);
        }
        else if(ret > 0)
        {
            cout<<"got "<<val<<endl;
            client.send(&val, 1);
            if(val == '\n')
            {
                cout<<"Got end of string!"<<endl;
                break;
            }
        }
        else {//empty}
    }
    */
    #pragma endregion server_connect 
    
    int ret = _txSock.connect("192.168.1.10", "5000"); //sends
    cout << "_txSock connected status: " << ret << endl;
    int ret2 = _rxSock.connect("192.168.1.10", "5001"); //receives
    cout<< "_rxSock connected status: " << ret2 << endl;

    char msgData[] = {"connect\n"};
    _rxSock.send(msgData);

    char c;
    bool done = false;
    while(!done)
    {
        int ret = _rxSock.recv(&c, 1, VirtualSocket::WAIT);
        if(ret > 0)
        {
            cout<<"got "<<c<<endl;
        }
        else if(ret == 0)
        {
            cout<<"Done because the server disconnected"<<endl;
            done = true;
        }
        else
        {
            cerr<<"Error in recv: "<<ret<<endl;
            exit(1);
        }
    }
    cout<<"DONE!!"<<endl;

    return ret;
}
With this, I still am getting stuck in my recv -> accept function, however, it is now giving me this information attached below. I have tried researching it but have not had any success in finding a fix for the "IP Errors". This means it knows it is supposed to be getting a message, but is not... do you know any way to fix this or any documentation that covers this? Thank you again and best!
pcan help 2.PNG
pcan help 2.PNG (147.05 KiB) Viewed 2851 times

tjlarso
Posts: 4
Joined: Wed 12. Jun 2024, 16:21

Re: Ethernet Gateway DR - Sending but not Receive using Sockets

Post by tjlarso » Thu 13. Jun 2024, 16:34

here is also my poi_config for my gateway to potentially provide a little more context for you.

Code: Select all

#########################################
# PoI configuration file
# 
# BSP version 2.9.1
######################################### 
[general]
ini_version                    = 2.0.1
description                    = CAN to LAN Gateway in DIN Rail Plastic Casing
kl15_pwdn                      = 0
device_id                      = 2147483647


[host]
devicename                     = PCAN-Ethernet Gateway DR


[lan_0]
if_name                        = eth0
use_dhcp                       = 0
ip_v4                          = 192.168.1.10
subnet_mask                    = 255.255.255.0
ip_v6                          = ::
ip_v4_gw                       = 0.0.0.0
ip_v6_gw                       = ::


[can_0]
if_name                        = First CAN interface
active                         = 1
listen_only                    = 0
auto_resume                    = 1
loop_back                      = 0
one_shot                       = 0
triple_sampling                = 0
br_def                         = 0
core_clock                     = 24000000
bit_rate                       = 500000
sample_point                   = 800
enable_error_counter           = 0
measure_bus_load               = 0


[can_1]
if_name                        = Second CAN interface
active                         = 1
listen_only                    = 0
auto_resume                    = 1
loop_back                      = 0
one_shot                       = 0
triple_sampling                = 0
br_def                         = 0
core_clock                     = 24000000
bit_rate                       = 500000
sample_point                   = 800
enable_error_counter           = 0
measure_bus_load               = 0


[rt_0]
rt_info                        = 
active                         = TRUE
type                           = LAN2CAN
interface_1                    = can0
protocol_2                     = TCP
destination_2                  = 0.0.0.0:5000
fpp                            = 15
tcp_delay                      = TRUE
disp_idx                       = 0
snd_delay_us                   = 1000
snd_max                        = 30
connect_delay_ms               = 500
invert_socket_mode             = FALSE
use_crc_frm                    = FALSE
crc_start_value                = 0x00000000
crc_polynom                    = 0x04C11DB7
no_ctrl                        = TRUE
no_keep_alive                  = FALSE
unify_filters                  = FALSE
join_filters                   = FALSE


[fwd_gen]
count_max                      = 16
count                          = 2


[gui]
show_device_info               = 1
show_can_info                  = 0
show_lan_info                  = 0
show_wlan_info                 = 0
show_bt_info                   = 0
show_routing_info              = 0
show_contact_info              = 1
show_support_info              = 1
show_filter_info               = 1


[json]
enable_json                    = 1
respect_gui_pub                = 1
enable_json_config             = 0
enable_json_shell              = 0


[rt_1]
rt_info                        = 
active                         = TRUE
type                           = CAN2LAN
interface_1                    = can0
protocol_2                     = TCP
destination_2                  = 0.0.0.0:5001
fpp                            = 15
tcp_delay                      = TRUE
disp_idx                       = 0
snd_delay_us                   = 300
snd_max                        = 30
connect_delay_ms               = 500
invert_socket_mode             = TRUE
use_crc_frm                    = FALSE
crc_start_value                = 0x00000000
crc_polynom                    = 0x04C11DB7
no_ctrl                        = TRUE
no_keep_alive                  = FALSE
unify_filters                  = FALSE
join_filters                   = FALSE



M.Heidemann
Sales & Support
Sales & Support
Posts: 1083
Joined: Fri 20. Sep 2019, 13:31

Re: Ethernet Gateway DR - Sending but not Receive using Sockets

Post by M.Heidemann » Thu 13. Jun 2024, 16:45

Please have another look at the examples, your code seems to skip crucial steps here:

Code: Select all


	/* Set socket option SO_REUSEADDR
	 * Indicates that the rules used in validating addresses supplied in a bind(2)
	 *  call should allow reuse of local addresses. For PF_INET sockets this means
	 *  that a socket may bind, except when there is an active listening socket bound
	 *  to the address. When the listening socket is bound to INADDR_ANY with a specific
	 *  port then it is not possible to bind to this port for any local address.
	 */
	retVal = setsockopt(sockID, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
	if(retVal < 0){
		perror("error using setsockopt (SOL_SOCKET, SO_REUSEADDR)");
		exit(-2);			   				/* Rückkehr bei Fehler */
	}

	// Enable keepalive packets
	retVal = setsockopt(sockID, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
	if(retVal < 0){
		perror("error using setsockopt (SOL_SOCKET, SO_KEEPALIVE)");
		exit(-2);			   				/* Rückkehr bei Fehler */
	}

	retVal = setsockopt(sockID, SOL_IP, IP_RECVERR, &optval, sizeof(int));
	if(retVal < 0){
		perror("error using setsockopt (SOL_IP, IP_RECVERR)");
		exit(-2);			   				/* Rückkehr bei Fehler */
	}

	//Config Socket
	memset((char *) &sockname, 0, sizeof(struct sockaddr_in));	/* unbenutzte Bytes loeschen! */
	sockname.sin_family = AF_INET;	   							/* IP-Adresse aufsetzen */
	sockname.sin_port = htons(port);							/* Portnummer des Services */
	sockname.sin_addr.s_addr = htonl(INADDR_ANY);				/* wildcard */


    if (bind(sockID, (const struct sockaddr*) &sockname, sizeof(sockname)) < 0){	    /* an Adresse binden */
		perror("unable to bind socket");
		exit(-2);			   				/* Rückkehr bei Fehler */
    }

    if (type == SOCK_STREAM){
    	struct sockaddr peer_addr;
    	socklen_t addr_len;

		if (listen(sockID, queue_len) < 0){
			perror("unable to listen to clients");
			exit(-2);			   				/* Rückkehr bei Fehler */
		}

		sockID = accept(sockID, &peer_addr, &addr_len);
    }

	return sockID;
}//priv_openSocketIn()
I don't see much in terms of socket configuration, for example.

Can you tell me, what exactly you are trying to achieve that is not covered by the example?

Best Regards

Marvin
---
Marvin Heidemann
PEAK-Support Team

tjlarso
Posts: 4
Joined: Wed 12. Jun 2024, 16:21

Re: Ethernet Gateway DR - Sending but not Receive using Sockets

Post by tjlarso » Thu 13. Jun 2024, 21:42

No worries Marvin! I have revisited the code since my last comment and it is all working as expected now! I appreciate your help today on this topic and wish you the kindest of regards.

Best and thank you,
TJ

M.Heidemann
Sales & Support
Sales & Support
Posts: 1083
Joined: Fri 20. Sep 2019, 13:31

Re: Ethernet Gateway DR - Sending but not Receive using Sockets

Post by M.Heidemann » Fri 14. Jun 2024, 13:59

That's great to hear!

If you have any further questions, feel free to create a new topic!

BR

Marvin

-closed-
---
Marvin Heidemann
PEAK-Support Team

Locked