TCP client cannot connect to Python TCP server: timeout

Hello,

Summary:

  • Environnement
  • Previous post
  • What I want to do
  • What I have done
  • What my problem is
  • Questions
  • Code sample

##### ENVIRONMENT #####
Card : STM32H723ZG
PC : Computer with Windows 10
IDE : stm32cubeIDE
Compiler : GCC 9.2.0
FreeRTOS : 202212.01TCP client cannot connect to Pythons TCP server: timeout

##### PREVIOUS POST #####

##### WHAT I WANT TO DO #####
I want to create a TCP connection between an stm32h723zg and a computer running a TCP server in Python.

##### What I have done #####
I was able to make a simple FreeRTOS project with 2 tasks. I then moved to to initializing FreeRTOS plus TCP. I made a server.

Regarding the client part : I created the socket and binded it to a port.

Regarding the PC part in Python : I made a server that waits for a connection and a client that connects by specifying the port and the IP and sends a message. When a client connects to the pyhton server, the server output the infromations of the client (IP and port).

##### What my problem is #####
I am now trying to connect the client to the remote server that I know the IP and port of.

I have tried 3 approaches :

  • Create the socket in the task then call a function to connect then call a function to send data

  • Make it as close as possible from the exemple : TCP Networking Tutorial - Send Data Using a TCP Socket

  • Make it as close as possible to the demo “FreeRTOS_Plus_TCP_Echo_Posix”

For each approaches I went into debug mode and tried to find the issue but I just ended up entering functions after functions and looping inside the same functions without knowing what their purpose was.
This debut method wasn’t very successful, that’s why I added prints everywhere. In the code I share I greatly reduce the amount of prints.

Approach 1

I follow this example to create the task createClientSocket :

I followed this exemple to create the connect function and the send data function (however, I did not create the socket in the send function as I already created it previously) :

When I run it, nothing changes in the console running the TCP server (same for all 3 approaches) and in the Putty terminal I get :

GG : Init successful, starting scheduler. (main.c)
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
Autonego ready: 00000004: full duplex 100 mbit high status
Network buffers: 56 lowest 56
Link Status is high
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
Network buffers: 56 lowest 55
RX descriptors 7/8
vDHCPProcess: offer a012364ip
vDHCPProcess: reply a012364ip
vDHCPProcess: offer a012364ip
vDHCPProcess: acked a012364ip


IP Address: 10.1.35.100
Subnet Mask: 255.255.255.0
Gateway Address: 10.1.35.254
DNS Client Address: 192.168.73.220


        GG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 1. (main.c)

        GG : Entered prvClientConnectToServer. (main.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
FreeRTOS_connect: 39001 to a012372ip:50053
GG : xSendEventToIPTask started. (FreeRTOS_Sockets.c)
ARP for a012372ip (using a012372ip): rc=0 00:00:00 00:00:00
Coap: current 20320 lowest 20320
                                meout 1: 500 ms
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Entered "if" : TCPconnectStart succeeded (FreeRTOS_connect FreeRTOS_Sockets.c).
prvSocketSetMSS: 536 bytes for a012372ip:50053
Connect[a012372ip:50053]: next timeout 1: 3000 ms
Connect[a012372ip:50053]: next timeout 2: 6000 ms
Connect[a012372ip:50053]: next timeout 3: 11000 ms
Connect: giving up a012372ip:50053
Move from eCONNECT_SYN to eCLOSE_WAIT
FreeRTOS_connect() stopped due to an error
GG : Client connection to server FAILED. (main.c)

Note that the lines starting by "GG : " are debug prints that I added.

The STM tries to connect but gets timedout.
I tried increasing the network buffer descriptors from 60 to 64 as 56 seemed dangerously close to 55.
I also tried decreasing the Rx Descriptors from 8 to 7 because “RX descriptors 7/8”, in this case, that line change to “RX descriptors 6/7”.
The IP I am trying to connect to is 10.1.35.114 which in hexa is 0x0a012364 and we can read a012364ip. It seemed the initial 0 is missing but I don’t think it is the issue.

Approach 2

I tried to make it as close as possible to the send data exemple because they do eevrything inside a function.

Here is the putty output I get : 
GG : Init successful, starting scheduler. (main.c)
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
Autonego ready: 00000004: full duplex 100 mbit high status
Network buffers: 56 lowest 56
Link Status is high
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
Network buffers: 56 lowest 55
RX descriptors 7/8
vDHCPProcess: offer a012364ip
vDHCPProcess: reply a012364ip
vDHCPProcess: offer a012364ip
vDHCPProcess: acked a012364ip


IP Address: 10.1.35.100
Subnet Mask: 255.255.255.0
Gateway Address: 10.1.35.254
DNS Client Address: 192.168.73.220


        GG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 2. (main.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)

Here it didn’t even try to connect.

Approach 3

I tried to make it as close as possible to the demo example (that I did not implement by itself. The whole process seemed weird is it is quite different than my first approach like they are using win, they are setting the IP as static (while I have to use DHCP).

It basicaly gave me the same results as the first approach :

GG : Init successful, starting scheduler. (main.c)
prvIPTask started
PHY ID 7C130
xPhyReset: phyBMCR_RESET 0 ready
+TCP: advertise: 01E1 config 3100
prvEthernetUpdateConfig: LS mask 00 Force 1
Autonego ready: 00000004: full duplex 100 mbit high status
Link Status is high
prvInitialiseDHCP: start after 250 ticks
vDHCPProcess: discover
Network buffers: 60 lowest 59
RX descriptors 7/8
vDHCPProcess: offer a012364ip
vDHCPProcess: reply a012364ip
vDHCPProcess: offer a012364ip
vDHCPProcess: acked a012364ip


IP Address: 10.1.35.100
Subnet Mask: 255.255.255.0
Gateway Address: 10.1.35.254
DNS Client Address: 192.168.73.220


        GG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 3. (main.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)
GG : Couldn't enter "if" : connect fail (FreeRTOS_connect FreeRTOS_Sockets.c)
GG : Bind the socket to the port that the client task will send from. Non-standard, so the error returned is that returned by bind(). (FreeRTOS_SOckets.c)
GG : prvTCPConnectStart finished. (FreeRTOS_SOckets.c)

Note that I did not copy apste everything because the call to the connect function is inside a for( ; ; ) so we get the same prints all the time.

Note also that I changed the FreeRTOSIPConfig.h file to the one given in the demo, making sure to set USETCP and USEDHCP to 1.

##### QUESTION #####
Project download : Download files - Filemail

Is there an obvious mistake I made?
What is causing the stm32 to not be able to connect (timeout)?

##### CODE SAMPLE #####
To test the different approaches you have to change GG_CLIENT_TEST to either 1, 2 or 3 in the FreeRTOSIPConfig.h file.

Project download : Download files - Filemail

FreeRTOSIPConfig.h (note that there is both my config and the demo config):

#ifndef FREERTOS_IP_CONFIG_H
#define FREERTOS_IP_CONFIG_H

#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN

#define GG_CLIENT_TEST							3

// Config from the demo
/*
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM  	 1
#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME		( 5000 )
#define	ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME		( 5000 )
#define ipconfigUSE_DNS_CACHE						( 1 )
#define ipconfigDNS_CACHE_NAME_LENGTH				( 16 )
#define ipconfigDNS_CACHE_ENTRIES					( 4 )
#define ipconfigDNS_REQUEST_ATTEMPTS				( 2 )
#define ipconfigIP_TASK_PRIORITY					( configMAX_PRIORITIES - 2 )
#define ipconfigIP_TASK_STACK_SIZE_WORDS			( configMINIMAL_STACK_SIZE * 5 )
extern UBaseType_t uxRand();
#define ipconfigRAND32()							uxRand()
#define ipconfigUSE_NETWORK_EVENT_HOOK 				1
#define	ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS    	pdMS_TO_TICKS( 2500U )	//For a DNS lookup, it is important to set the following config items:
#define	ipconfigDNS_SEND_BLOCK_TIME_TICKS       	pdMS_TO_TICKS( 2500U )	// source : https://forums.freertos.org/t/failed-to-connect-to-server-freertos-connect-failed-returncode-116-freertos-tcp/15620/11
#define ipconfigUSE_DHCP 							1
#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD			( 120000U / portTICK_PERIOD_MS )
#define ipconfigARP_CACHE_ENTRIES					6
#define ipconfigMAX_ARP_RETRANSMISSIONS 			( 5 )
#define ipconfigMAX_ARP_AGE							150
#define ipconfigINCLUDE_FULL_INET_ADDR				1
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS		60
#define ipconfigEVENT_QUEUE_LENGTH					( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 		1
#define ipconfigUDP_TIME_TO_LIVE					128
#define ipconfigTCP_TIME_TO_LIVE					128
#define ipconfigUSE_TCP								1
#define ipconfigUSE_TCP_WIN							0	//win
#define ipconfigNETWORK_MTU							1200U
#define ipconfigUSE_DNS								0
#define ipconfigREPLY_TO_INCOMING_PINGS				1
#define ipconfigSUPPORT_OUTGOING_PINGS				0
#define ipconfigSUPPORT_SELECT_FUNCTION				1
#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES  	1
#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES	1
#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS )
#define ipconfigPACKET_FILLER_SIZE 					2U
#define ipconfigTCP_WIN_SEG_COUNT					240
#define ipconfigTCP_RX_BUFFER_LENGTH				( 1000 )
#define ipconfigTCP_TX_BUFFER_LENGTH				( 1000 )
#define ipconfigIS_VALID_PROG_ADDRESS(x) ( (x) != NULL )
#define ipconfigTCP_HANG_PROTECTION					( 1 )
#define ipconfigTCP_HANG_PROTECTION_TIME			( 30 )
#define ipconfigTCP_KEEP_ALIVE						( 1 )
#define ipconfigTCP_KEEP_ALIVE_INTERVAL				( 20 )//in seconds
#define portINLINE __inline
*/



//	My own config

#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS      64	//a small number, idk how small...
#define ipconfigUSE_NETWORK_EVENT_HOOK 				1	// If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the network event hook at the appropriate times
#define ipconfigZERO_COPY_RX_DRIVER                 1
#define ipconfigZERO_COPY_TX_DRIVER                 1
#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM		1
#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM		1
#define ipconfigUSE_NETWORK_EVENT_HOOK 				1
#define ipconfigDNS_USE_CALLBACKS					1
#define ipconfigDNS_CACHE_NAME_LENGTH				20
#define ipconfigUSE_TCP								1	//if 0, use UDP by default
#define ipconfigTCP_KEEP_ALIVE						0	//If FreeRTOS-Plus-TCP does not receive a reply to a keep alive message then the connection will be broken
#define ipconfigTCP_HANG_PROTECTION					1	//will mark a socket as closed if there is no status change on the socket
#define ipconfigTCP_HANG_PROTECTION_TIME			60	//within the period of time specified in seconds
#define ipconfigUSE_TCP_WIN       					0	//If you have a tiny CPU with less than 64KB of RAM, do not use sliding Windows
//define below based on freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration_Examples.html
#define ipconfigTCP_TX_BUFFER_LENGTH   				( 2 * ipconfigTCP_MSS )
#define ipconfigTCP_RX_BUFFER_LENGTH   				( 2 * ipconfigTCP_MSS )
#define ipconfigNETWORK_MTU   						586
#define ipconfigTCP_MSS       						522
#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND		1	// Should allow freertos to select a working port if no one is given


#define ipconfigHAS_PRINTF 1
#define FreeRTOS_debug_printf( x ) printf x
#define FreeRTOS_printf( x ) printf x
#endif /* FREERTOS_IP_CONFIG_H */

main.c :

/* Standard includes. */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include <ctype.h>

/* cubeMX/HAL includes */
#include "main.h"
#include "string.h"

/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
#include "semphr.h"

/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_DHCP.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
#include "phyHandling.h"
#if( ipconfigMULTI_INTERFACE != 0 )
	#include "FreeRTOS_Routing.h"
	#include "FreeRTOS_ND.h"
#endif

/* Macro to check if socket is bound, copy pasted from FreeRTOS_Socket.c */
#define socketSOCKET_IS_BOUND( pxSocket )            ( listLIST_ITEM_CONTAINER( &( pxSocket )->xBoundSocketListItem ) != NULL )

#define usUsedStackSize 128
#define BUFFER_SIZE 512

/* cube mx generated handler */
ETH_HandleTypeDef heth;
UART_HandleTypeDef huart3;
ETH_TxPacketConfig TxConfig;

/* The MAC address array is not declared const as the MAC address will
normally be read from an EEPROM and not hard coded (in real deployed applications).*/
static uint8_t ucMACAddress[ 6 ] = { 0x00, 0x80, 0xE1, 0x00, 0x00, 0x00 };

/* Define the network addressing.  These parameters will be used if either
ipconfigUDE_DHCP is 0 or if ipconfigUSE_DHCP is 1 but DHCP auto configuration failed. */
static const uint8_t ucIPAddress[ 4 ];
static const uint8_t ucNetMask[ 4 ];
static const uint8_t ucGatewayAddress[ 4 ];

/* The following is the address of the DNS client. */
static const uint8_t ucDNSClientAddress[ 4 ] = { 192, 168, 73, 220 };

/* Random Number Generator variable. */
static RNG_HandleTypeDef hrng;

/* cube MX generated function definitions */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_USB_OTG_HS_USB_Init(void);
static void MX_RNG_Init(void);

/* TCP function definition */
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent );
BaseType_t xApplicationGetRandomNumber( uint32_t *pulValue );
void prvClientConnectToServer(Socket_t xSocket);
void prvClientSendData(Socket_t xSocket);
void vTCPSend(void);

/* TCP task function definitions (the ones that do tcp thing */
static void vCreateTCPClientSocket(void *pvParameters);

/* Functions */


int main(void)
{
	/* cube mx init */
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_USART3_UART_Init();
	MX_USB_OTG_HS_USB_Init();
  
    /*Rng init*/
	MX_RNG_Init();

	/* TCP init */
	FreeRTOS_IPInit(ucIPAddress,
	                ucNetMask,
	                ucGatewayAddress,
	                ucDNSClientAddress,
	                ucMACAddress );

	/* task creation */
	NVIC_EnableIRQ(ETH_IRQn);
	NVIC_SetPriority(ETH_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);

	/* starting rtos scheduler */
	FreeRTOS_printf( ( "\033[2J") );	/* Clean putty */
	FreeRTOS_printf( ( "\r\nGG : Init successful, starting scheduler. (main.c)\r\n") );
	vTaskStartScheduler();
}

static void vCreateTCPClientSocket(void *pvParameters)
{
#if GG_CLIENT_TEST == 1 //create socket in task then call function to connect then call function to send data
	/* Variables */
	struct freertos_sockaddr xClient, xRemoteAddress;
	Socket_t xClientSocket;
	socklen_t xSize = sizeof( xClient );
	static const TickType_t xTimeOut = portMAX_DELAY;

	FreeRTOS_printf(("\tGG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 1. (main.c)\r\n"));

	/* Socket creation. */
	xClientSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);	/* Attempt to open the socket. */
	configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET );										/* Check the socket was created. */

	/* Binding (not necessary) */
	xClient.sin_port = FreeRTOS_htons(585);	// en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
	FreeRTOS_bind(xClientSocket, &xClient, xSize);

	/* Set a time out so accept() will just wait for a connection. */
	FreeRTOS_setsockopt(xClientSocket, 0, FREERTOS_SO_RCVTIMEO, &xTimeOut, sizeof(xTimeOut));
	FreeRTOS_setsockopt(xClientSocket, 0, FREERTOS_SO_SNDTIMEO, &xTimeOut, sizeof(xTimeOut));

	/*Function to connect to the server */
	prvClientConnectToServer(xClientSocket);

#elif GG_CLIENT_TEST == 2 //make it as close as the example from the website : freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial_Sending_TCP_Data.html
	/* Variables */
	Socket_t xSocket;
	struct freertos_sockaddr xRemoteAddress;
	BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
	// unused TaskHandle_t xRxTask = NULL;
	size_t xLenToSend;
	/* The 2 variables below are parameters of the function in the example but I don't use this code as a function so I have to init them */
	char *pcBufferToTransmit = "Hey buddy!";
	const size_t xTotalLengthToSend = 10;

	FreeRTOS_printf(("\tGG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 2. (main.c)\r\n"));

	/* Set the IP address and port of the remote socket to which this client socket will transmit. */
	xRemoteAddress.sin_port = FreeRTOS_htons(50053);
	xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick(10, 1, 35, 114);

	/* Create a socket. */
	xSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);
	configASSERT(xSocket != FREERTOS_INVALID_SOCKET);

	/* Connect to the remote socket.  The socket has not previously been bound to a local port number so will get automatically bound. */
	if( FreeRTOS_connect(xSocket, &xRemoteAddress, sizeof(xRemoteAddress)) == 0)
	{
		while(xAlreadyTransmitted < xTotalLengthToSend) /* Keep sending until the entire buffer has been sent. */
		{
			xLenToSend = xTotalLengthToSend - xAlreadyTransmitted; /* How many bytes are left to send? */
			xBytesSent = FreeRTOS_send(xSocket, &(pcBufferToTransmit[xAlreadyTransmitted]), xLenToSend, 0);

			if(xBytesSent >= 0) xAlreadyTransmitted += xBytesSent;
			else break;
		}
	}

	/* Initiate graceful shutdown. */
	FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );

	/* Wait for the socket to disconnect gracefully before closing the socket. */
	while(FreeRTOS_recv(xSocket, pcBufferToTransmit, xTotalLengthToSend, 0) >= 0)
	{
		vTaskDelay(pdMS_TO_TICKS(250)); /* Wait for shutdown to complete. */
		/* Note - real applications should implement a timeout here, not just loop forever. */
	}

	/* The socket has shut down and is safe to close. */
	FreeRTOS_closesocket(xSocket);

#elif GG_CLIENT_TEST == 3 //everything in a single task (like the demo)
	/* Variables */
	struct freertos_sockaddr xRemoteAddress;
	Socket_t xClientSocket;
	BaseType_t ret;

	FreeRTOS_printf(("\tGG : Entered vCreateTCPClientSocket with GG_CLIENT_TEST value of 3. (main.c)\r\n"));

	/* Set the IP address and port*/
	xRemoteAddress.sin_port = FreeRTOS_htons(50053);
	xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick(10, 1, 35, 114);

	for(;;)
	{
		/* Socket creation. */
		xClientSocket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);	/* Attempt to open the socket. */
		configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET );										/* Check the socket was created. */

		ret = FreeRTOS_connect(xClientSocket, &xRemoteAddress, sizeof(xRemoteAddress));

		if( ret == 0 ) FreeRTOS_printf(("GG : Client connection to server. (main.c)\r\n"));
	}

#else
  #error Unsupported choice setting

#endif /* end #if GG_CLIENT_TEST */
}

void prvClientConnectToServer(Socket_t xSocket)	/* case 1 */
{
	struct freertos_sockaddr xRemoteAddress;

	FreeRTOS_printf(("\n\tGG : Entered prvClientConnectToServer. (main.c)\r\n"));

	/* Set the IP address and port*/
	xRemoteAddress.sin_port = FreeRTOS_htons(50053);
	xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick(10, 1, 35, 114);

	if( FreeRTOS_connect(xSocket, &xRemoteAddress, sizeof(xRemoteAddress)) == 0)
	{
		FreeRTOS_printf(("GG : Client connection to server successful. (main.c)\r\n"));
		prvClientSendData(xSocket);
	}
	else FreeRTOS_printf(("GG : Client connection to server FAILED. (main.c)\r\n"));
}

void prvClientSendData(Socket_t xSocket) /* case 1 */
{
	//struct freertos_sockaddr xRemoteAddress;
	BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
	size_t xLenToSend;

	char *pcBufferToTransmit = "Hey buddy!";
	const size_t xTotalLengthToSend = 10;

	FreeRTOS_printf(("\tGG : Entered prvClientSendData. (main.c)\r\n"));

	/* Ensure termination */
	//pcBufferToTransmit[xTotalLengthToSend] = '\0';

	if( !socketSOCKET_IS_BOUND( xSocket ) )	/* if client socket had already be bound (bind) we can continue */
	{	FreeRTOS_printf(("GG : rtos connected. (main.c)\r\n"));
		/* Keep sending until the entire buffer has been sent. */
		while(xAlreadyTransmitted < xTotalLengthToSend)
		{	FreeRTOS_printf(("GG : entered while. (main.c)\r\n"));
			/* How many bytes are left to send? */
			xLenToSend = xTotalLengthToSend - xAlreadyTransmitted;
			xBytesSent = FreeRTOS_send(/* The socket being sent to. */
										xSocket,
										/* The data being sent. */
										&( pcBufferToTransmit[ xAlreadyTransmitted ] ),
										/* The remaining length of data to send. */
										xLenToSend,
										/* ulFlags. */
										0 );
			if( xBytesSent >= 0 )
			{	/* Data was sent successfully. */
				xAlreadyTransmitted += xBytesSent;
			}
			else
			{	/* Error - break out of the loop for graceful socket close. */
				break;
			}
		}
	}
	FreeRTOS_printf(("GG : Done transmiting, starting clean exit. (main.c)\r\n"));
	/* Initiate graceful shutdown. */
	FreeRTOS_shutdown(xSocket, FREERTOS_SHUT_RDWR);

	/* Wait for the socket to disconnect gracefully before closing the socket. */
	while( FreeRTOS_recv(xSocket, pcBufferToTransmit, xTotalLengthToSend, 0) >= 0)
	{
		/* Wait for shutdown to complete. */
		vTaskDelay(pdMS_TO_TICKS(250));

		/* Note - real applications should implement a timeout here, not just
		loop forever. */
	}

	/* The socket has shut down and is safe to close. */
	FreeRTOS_closesocket( xSocket );
	FreeRTOS_printf(("GG : Clean exit finished. (main.c)\r\n"));
}

void vTCPSend(void)
{
	Socket_t xSocket;
	struct freertos_sockaddr xRemoteAddress;
	BaseType_t xAlreadyTransmitted = 0, xBytesSent = 0;
	TaskHandle_t xRxTask = NULL;
	size_t xLenToSend;

	FreeRTOS_printf(("\tGG : Entered vTCPSend. (main.c)\r\n"));

	char *pcBufferToTransmit = "Hey buddy!";
	const size_t xTotalLengthToSend = 10;

    /* Set the IP address and port of the remote socket to which this client socket will transmit. */
    xRemoteAddress.sin_port = FreeRTOS_htons( 50053 );
    xRemoteAddress.sin_addr = FreeRTOS_inet_addr_quick(10, 1, 35, 114);

    /* Create a socket. */
    xSocket = FreeRTOS_socket( FREERTOS_AF_INET,
                               FREERTOS_SOCK_STREAM,/* FREERTOS_SOCK_STREAM for TCP. */
                               FREERTOS_IPPROTO_TCP );
    FreeRTOS_printf(("GG : Testing config assert.\r\n"));
    configASSERT( xSocket != FREERTOS_INVALID_SOCKET );
    FreeRTOS_printf(("GG : Config assert passed, creating connection. (main.c)\r\n"));

    /* Connect to the remote socket.  The socket has not previously been bound to
    a local port number so will get automatically bound to a local port inside
    the FreeRTOS_connect() function. */
    if( FreeRTOS_connect( xSocket, &xRemoteAddress, sizeof( xRemoteAddress ) ) == 0 )
    {
    	FreeRTOS_printf(("GG : Connection successful. (main.c)\r\n"));
        /* Keep sending until the entire buffer has been sent. */
        while( xAlreadyTransmitted < xTotalLengthToSend )
        {
            /* How many bytes are left to send? */
            xLenToSend = xTotalLengthToSend - xAlreadyTransmitted;
            xBytesSent = FreeRTOS_send( /* The socket being sent to. */
                                        xSocket,
                                        /* The data being sent. */
                                        &( pcBufferToTransmit[ xAlreadyTransmitted ] ),
                                        /* The remaining length of data to send. */
                                        xLenToSend,
                                        /* ulFlags. */
                                        0 );

            if( xBytesSent >= 0 )
            {
                /* Data was sent successfully. */
                xAlreadyTransmitted += xBytesSent;
            }
            else
            {
                /* Error - break out of the loop for graceful socket close. */
                break;
            }
        }
    }
    else FreeRTOS_printf(("GG : Connection failed. (main.c)\r\n"));

    /* Initiate graceful shutdown. */
    FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );

    /* Wait for the socket to disconnect gracefully (indicated by FreeRTOS_recv()
    returning a -pdFREERTOS_ERRNO_EINVAL error) before closing the socket. */
    while( FreeRTOS_recv( xSocket, pcBufferToTransmit, xTotalLengthToSend, 0 ) >= 0 )
    {
        /* Wait for shutdown to complete.  If a receive block time is used then
        this delay will not be necessary as FreeRTOS_recv() will place the RTOS task
        into the Blocked state anyway. */
        vTaskDelay( pdMS_TO_TICKS( 250 ) );

        /* Note - real applications should implement a timeout here, not just
        loop forever. */
    }

    /* The socket has shut down and is safe to close. */
    FreeRTOS_closesocket( xSocket );
}

void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
  static BaseType_t xTasksAlreadyCreated = pdFALSE;
  uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSClientAddress;
  char cBuffer[ 16 ];

    /* Both eNetworkUp and eNetworkDown events can be processed here. */
    if( eNetworkEvent == eNetworkUp )
    {
        /* Create the tasks that use the TCP/IP stack if they have not already
        been created. */
        if( xTasksAlreadyCreated == pdFALSE )
        {
            /*
             * For convenience, tasks that use FreeRTOS-Plus-TCP can be created here
             * to ensure they are not created before the network is usable.
             */
        	xTaskCreate(vCreateTCPClientSocket,
        	            "clientSocket",
        	            usUsedStackSize,
        	            NULL,
        	            tskIDLE_PRIORITY,
        	            NULL);

            xTasksAlreadyCreated = pdTRUE;
            //xIPTaskInitialised = pdTRUE;
        }

        FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSClientAddress );

        FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
        FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );

        FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
        FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );

        FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
        FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );

        FreeRTOS_inet_ntoa( ulDNSClientAddress, cBuffer );
        FreeRTOS_printf( ( "DNS Client Address: %s\r\n\r\n\r\n", cBuffer ) );
    }
}

/* Random Number Generator function*/
BaseType_t xApplicationGetRandomNumber( uint32_t *pulValue )
{
HAL_StatusTypeDef xResult;
BaseType_t xReturn;
uint32_t ulValue;

	xResult = HAL_RNG_GenerateRandomNumber( &hrng, &ulValue );
	if( xResult == HAL_OK )
	{
		xReturn = pdPASS;
		*pulValue = ulValue;
	}
	else
	{
		xReturn = pdFAIL;
	}
	return xReturn;
}

/**
  * @brief RNG Initialization Function
  * @param None
  * @retval None
  */
static void MX_RNG_Init(void)
{
  hrng.Instance = RNG;
  //hrng.Init.ClockErrorDetection = RNG_CED_ENABLE;
  if (HAL_RNG_Init(&hrng) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 275;
  RCC_OscInitStruct.PLL.PLLP = 1;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief USART3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART3_UART_Init(void)
{
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief USB_OTG_HS Initialization Function
  * @param None
  * @retval None
  */
static void MX_USB_OTG_HS_USB_Init(void)
{
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, LED_GREEN_Pin|LED_RED_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(USB_FS_PWR_EN_GPIO_Port, USB_FS_PWR_EN_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_YELLOW_GPIO_Port, LED_YELLOW_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : B1_Pin */
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : LED_GREEN_Pin LED_RED_Pin */
  GPIO_InitStruct.Pin = LED_GREEN_Pin|LED_RED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_FS_PWR_EN_Pin */
  GPIO_InitStruct.Pin = USB_FS_PWR_EN_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(USB_FS_PWR_EN_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_FS_OVCR_Pin */
  GPIO_InitStruct.Pin = USB_FS_OVCR_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USB_FS_OVCR_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_FS_VBUS_Pin */
  GPIO_InitStruct.Pin = USB_FS_VBUS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USB_FS_VBUS_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : USB_FS_ID_Pin */
  GPIO_InitStruct.Pin = USB_FS_ID_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_HS;
  HAL_GPIO_Init(USB_FS_ID_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : LED_YELLOW_Pin */
  GPIO_InitStruct.Pin = LED_YELLOW_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_YELLOW_GPIO_Port, &GPIO_InitStruct);
}

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM1 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM1) {
    HAL_IncTick();
  }
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  __disable_irq();
  while (1)
  {
  }
}

int _write(int file, char *ptr, int len)
{
  HAL_UART_Transmit(&huart3, ( const uint8_t * ) ptr, len, HAL_MAX_DELAY);
  HAL_UART_Transmit(&huart3, "\r", 1, HAL_MAX_DELAY);
  return len;
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

Thank you for reading me.
I will bring my computer home to be able to answer you.

Regards

Gaetan

Hi @GaetanGodart,

First, thank you for a very detailed post - it helps a ton :).

I will look more into this tomorrow, but on initial inspection, your code looks ok for setting up a connection. Are you sure you are connecting to the right IP (public vs local IP) and port?

I would suggest verifying that you can connect to the python server in a different way just to verify there are no issues with the python server itself - in fact if you could send the python code you are running that would also help. You could do this in a multitude of different ways - could even write a quick python client to connect to it - but I would recommend using netcat How To Use Netcat to Establish and Test TCP and UDP Connections | DigitalOcean.

To verify that the device side is working/able to connect to the internet - you could try having it connect to tcpbin.com (see FreeRTOS_gethostbyname() API Reference to get the ip from the hostname or alternatively you can just use tcpbin.com’s IP address (45.79.112.203)) being sure to use port 4242 for plaintext. tcpbin.com offers an echo server so anything you send to it will be sent back - so its a nice way to verify end-to-end.

Again, I will look more closely at your code tomorrow but this should help in the meantime.

Best,

Jason Carroll

Hi Jason,

Thank you for your answer.

I wanted to share my puthon server but I forgot, my bad.
I actually made a server and a client in python so the server “works” even thought it was on the same computer (I did not use localhost but instead set the correct IP).

I am using the local IP, the one I get when I type ipconfig on the terminal and the one I can see when typing arp -a in the terminal. When I type “what is my IP” in google I get a different address which is my public IP.
To be precise, both my computer and my STM are connected via eth cable to TRENDNET TE-100_55 which is a switch connected vie eth cable to the network of my company.
I was able previously to use this setup (but with “STM+ Raspberry” instead of “STM + computer”) to communicate in TCP using linux’s TCP functions.
I think it is arp’s job (or DNS’s job) to connect me to the right device when providing a private IP.

I will look into tcpbin.com thank you!

Here is the code for the python server and client :

server.py

"""
This is the server side of a basic python TCP/IP connection
Inspired by : docs.python.org/3/library/socket.html#timeouts-and-the-accept-method
"""
import socket, os

if __name__ == "__main__":
    """
    1) set host and port
    2) create socket
    3) bind
    4) listen
    5) connect
    """
    host = socket.gethostname() #Could also just put (host = ''), it gets the local machine 
    port = 50053
    with socket.socket() as s:  #if no parram, 1st param is socket.AF_INET and 2nd is  socket.SOCK_STREAM
        s.bind((host, port))
        print(f"Server (host : {host}) (port : {port}) (pid : {os.getpid()}) listening....")
        s.listen()
        conn, addr = s.accept()
        with conn:
            print('\tConnected by address :', addr)
            while True:
                data = conn.recv(1024).decode()
                if data == "shutdown" : break
                answer = (int(float(data)))*2
                print(f"\t\tReceived {data}")
                # Uncomment both line below if you want to answer aswell
                #print(f"sending {answer}")
                #conn.sendall(str.encode(str(answer)))
            conn.close()

client.py :

"""
This is the client side of a basic python TCP/IP connection
Inspired by : docs.python.org/3/library/socket.html#timeouts-and-the-accept-method
"""
import socket

if __name__ == "__main__":
    HOST = '10.1.35.114'      # The remote host
    PORT = 50053              # The same port as used by the server
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        print(f"Connected to {HOST} {PORT}")
        while(True):
            toBeSent = input("Enter the int to be doubled :")
            s.sendall(str.encode(toBeSent))
            print(f"Finished")
            if toBeSent == "shutdown":
                break   #exit if we sent shutdown
            # Uncomment both line below if you want to answer aswell
            #data = s.recv(1024)
            #print(f"Doubled value is : {data.decode()}")

This is what I get on my 2 terminals :

Server terminal (I start by launching this one obviously" :

D:\Documents\05 pyTest\myTCP>py serverTCP.py
Server (host : RNSPTP040P) (port : 50053) (pid : 4240) listening....
        Connected by address : ('10.1.35.114', 58895)
                Received 5
                Received 8
                Received 14

D:\Documents\05 pyTest\myTCP>

Client terminal (I launch it after the server one) :

D:\Documents\05 pyTest\myTCP>py clientTCP.py
Connected to 10.1.35.114 50053
Enter the int to be doubled :5
Finished
Enter the int to be doubled :8
Finished
Enter the int to be doubled :14
Finished
Enter the int to be doubled :shutdown
Finished

D:\Documents\05 pyTest\myTCP>

Finaly, here is a screenshoot of the terminals :

Thank you @GaetanGodart for the post.

I see you are trying to achieve a subset of an echo server. There is an STM32 project here with the echo server/client functionality : GitHub - kar-rahul-aws/STM32-NUCLEO-TCP-EchoClient-Demo at moni_update

Here is an example of a simple TCP echo server - https://github.com/kar-rahul-aws/STM32-NUCLEO-TCP-EchoClient-Demo/blob/moni_update/Demo/SimpleTCPEchoServer.c

Please check if this helps.

Also if using the same python script is not your requirement you can also use Hercules SETUP utility which can work as both client and server to check if that works fine to eliminate the possibility of issue with the python server.

Meanwhile i will try to check your project as well. Thank you

Hello Monika and thank your for your answer.

Both your links are 404.

I will check Hercules.

Hi @GaetanGodart,

Any success or new findings? I was unable to take a deeper look today into your code - but a good suggestion for debugging this on your end is to use Wireshark. If your device and host machine are connected to your LAN, you should be able to sniff packets sent from your device to your host machine.

Since you are using DHCP I can already tell that your device is able to talk to your router as your router assigns you your IP - that’s good!

Ok so since that’s already verified, you can sniff for packets sent to and from your device as seen by your host machine by using Wireshark with the filter ip.addr == your_device_ip. If you don’t see these packets - that would indicate that your router is not routing the packets your device sent to your host machine for whatever reason (device is sending to wrong IP would be the biggest one but I don’t think this applies here) or you might have selected the wrong network interface to sniff with Wireshark.

The reason I don’t think your device is sending to the wrong IP is because your python example showed that you were connecting to that IP (though, keep in mind that having your host machine connect to itself, even if using the IP address assigned by the router to connect, usually just has the host machine use a loopback (think localhost) rather than sending to and from the router - this isn’t super important to this but small tidbit).

If you don’t see any packets from above, the next thing to check would be to sniff for any ARP requests made by the device with the filter ( arp.src.proto_ipv4 == your_device_ip ) && ( arp.opcode==1 ) - you should see messages with Who has your_host_machine_ip? Tell your_device_ip - if you don’t see those that would be very strange as ARP requests are broadcasted and I can see at least in approach 1 that FreeRTOS-Plus-TCP makes an ARP request for your host machine’s IP.

But if you do see packets from the ip.addr filter with none of them coming from your machine (source of all packets is device ip - none with source as host machine ip) you probably just need to disable your firewall for your server port - thats more than likely the issue now that I think about it. Have you tried connecting another host machine to your LAN and running the python client to connect to your server - if this fails to connect that would be a clear indicator of a firewall issue.

Oh one last thing - remember to start sniffing packets with Wireshark and then power on your device.

Best,

Jason Carroll

The following were the issues in your project -

  1. Incorrectly implemented ulApplicationGetNextSequenceNumber.
  2. Incorrectly exiting form the TCP client task.
  3. Old RNG driver.

Here is the updated project -
H723ZG_freeRtosTcp_testBasic.7z (971.3 KB)

1 Like

Thank you for your help.

Gaurav, I looked at your answer and I will use your remarks to improve my project.

Jason, I asked my IT guy to “unlock” my firewall but after that I still cound’t connect.
I ran the server.py on my Raspberry and there I was able to connect and send a message.

Monika, I was able to connect to Hercules which told me there was an issue with my environment (python serevr or computer, turned out to be computer).

1 Like

You should be able to access it now. Please let me know if you face any issue.

Hi @GaetanGodart,

Were any of the suggestions able to help you resolve the issues you were seeing? Is there anything else we can help you with?

Thanks!

Yes, I was able to connect to hercules server so I figured thes server worked fine. Since I was able to connect to my Raspebrry but not my PC, I figured that this was a firewall issue.
I only used my PC as server for ease of access but my goal was to use the Raspberry as a server so everything Is (used to be) fine.

Yesterday when I started my computer adn Raspberry again and run the same code that ran perfectly the day prior, it was able to connect but I got stuck on the send function of FreeRTOS (happens randomly about half the time or more).
When debugging, I put a breakpoint at the send function and when I try to enter it I get a hardfault instantly. The PC points to the function listRemove_item. I googled it and someone had issue with it because he got a stack overflow so I increased the stack memory for the TCP task using the send function but that did not change anything.
I am thinking of making a separate post for this question.