+TCP. TCP connection is not established

Here is my server code:

static void prvSimpleServerTask( void *pvParameters )
{
#if (INFOINSHARK == 1)
	Socket_t xSharkWinSocket;
	struct freertos_sockaddr xSharkWinAddress;
#endif
	Socket_t xThisServerSocket, xThatClientSocket, xThisChildSocket;
	struct freertos_sockaddr xThisServerSocketAddress, xThatClientSocketAddress;
	static const TickType_t xTimeOut = pdMS_TO_TICKS( 200 );
	static const TickType_t xListingTimeOut = pdMS_TO_TICKS( 2000 );

	uint32_t ulCount = 0UL;
	int32_t status, lBytesReceived;

#if( ipconfigUSE_TCP_WIN == 1 )
	WinProperties_t xWinProps;
	xWinProps.lTxBufSize = ipconfigTCP_TX_BUFFER_LENGTH;
	xWinProps.lTxWinSize = 2;
	xWinProps.lRxBufSize = ipconfigTCP_RX_BUFFER_LENGTH;
	xWinProps.lRxWinSize = 2;
#endif /* ipconfigUSE_TCP_WIN */

#if (INFOINSHARK == 1)
	xSharkWinSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP);
	configASSERT( xSharkWinSocket != FREERTOS_INVALID_SOCKET );
	memset( &xSharkWinAddress, 0, sizeof(xSharkWinAddress) );
	xSharkWinAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr( "192.168.0.3" );
	xSharkWinAddress.sin_family = FREERTOS_AF_INET4;
	xSharkWinAddress.sin_port = FreeRTOS_htons( 10000 );
#endif
	vTaskDelay( pdTICKS_TO_MS( 1000 ) );
	for( ;; )
	{
		xThisServerSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP  );
		configASSERT( xThisServerSocket != FREERTOS_INVALID_SOCKET );

		FreeRTOS_setsockopt( xThisServerSocket, 0, FREERTOS_SO_RCVTIMEO, &xListingTimeOut, sizeof( xListingTimeOut ) );
		FreeRTOS_setsockopt( xThisServerSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );

		memset( &xThisServerSocketAddress, 0, sizeof(xThisServerSocketAddress) );
		xThisServerSocketAddress.sin_address.ulIP_IPv4 = FreeRTOS_inet_addr( "192.168.0.2" );
		xThisServerSocketAddress.sin_family = FREERTOS_AF_INET4;
		xThisServerSocketAddress.sin_port = 10000;
		xThisServerSocketAddress.sin_port = FreeRTOS_htons( xThisServerSocketAddress.sin_port );
		FreeRTOS_bind( xThisServerSocket, NULL, sizeof(xThisServerSocketAddress));

		#if (INFOINSHARK == 1)
		strcpy( WinInfoString, "FreeRTOS_bind xThisServerSocket");
		FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
		#endif

		volatile status = FreeRTOS_listen(xThisServerSocket, 5);
		if (status == 0)
		{
			#if (INFOINSHARK == 1)
			strcpy( WinInfoString, "FreeRTOS_listen without error");
			FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
			#endif
		}
		else
		{
			#if (INFOINSHARK == 1)
			strcpy( WinInfoString, "FreeRTOS_listen with error");
			FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
			#endif
		}
		do
		{
			xThisChildSocket = FreeRTOS_accept(xThisServerSocket, &xThatClientSocketAddress, sizeof( xThatClientSocketAddress ));
			configASSERT( xThisChildSocket != FREERTOS_INVALID_SOCKET );
			if (xThisChildSocket == 0)
			{
				#if (INFOINSHARK == 1)
				strcpy( WinInfoString, "Timeout FreeRTOS_accept");
				FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
				#endif
			}
			else
			{
				#if (INFOINSHARK == 1)
				strcpy( WinInfoString, "!!! xThisChildSocket have been got !!!");
				while(1){
					FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
					vTaskDelay( pdTICKS_TO_MS( 1000 ) );
				}
				#endif
			}
			vTaskDelay( pdTICKS_TO_MS( 50 ) );
		}
		while (xThisChildSocket == 0);

		#if (INFOINSHARK == 1)
		strcpy( WinInfoString, "xThisChildSocket = FreeRTOS_accept");
		FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
		#endif
		for(;;)
		{
			volatile lBytesReceived = FreeRTOS_recv( xThisChildSocket, &cString, 5000, 0 );
			if (lBytesReceived > 0)
			{
				#if (INFOINSHARK == 1)
				strcpy( WinInfoString, "FreeRTOS_recv > 0");
				FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
				#endif
			}
			if (lBytesReceived == 0)
			{
				#if (INFOINSHARK == 1)
				strcpy( WinInfoString, "FreeRTOS_recv == 0");
				FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
				#endif
			}
			if (lBytesReceived < 0)
			{
				#if (INFOINSHARK == 1)
				strcpy( WinInfoString, "FreeRTOS_recv < 0");
				FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
				#endif
				break;
			}
		}


		FreeRTOS_shutdown( xThisChildSocket, FREERTOS_SHUT_RDWR );
		#if (INFOINSHARK == 1)
		strcpy( WinInfoString, "FREERTOS_SHUT_RDWR");
		FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
		#endif

		while( FreeRTOS_recv( xThisChildSocket, cString, 5000, 0 ) >= 0 )
		{
		       vTaskDelay( pdTICKS_TO_MS( 250 ) );
		}
		FreeRTOS_closesocket( xThisChildSocket );
		#if (INFOINSHARK == 1)
		strcpy( WinInfoString, "FreeRTOS_closesocket xThisChildSocket");
		FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
		#endif

		vTaskDelay( pdTICKS_TO_MS( 1000 ) );
	}
}

ok, that is your problem. The control flow is wrong. Hint: Your xChildSocket is being improperly being reused in the do loop (among other problems). Please study existing TCP servers for a blueprint.

1 Like

I was sure that the problem was in my code.
Before this, I tried without cyclic (once). And still the FreeRTOS_accept function returned after a timeout.

For now I’m just trying to establish a connection. Does the client have the correct code to establish the connection?

Upon first glance it looks about right, but it is fairly convoluted code, so I can not say for sure without spending too much time on it. You may want to use an echo server sample and run your client against it to verify that. Alternatively, you may want to restart with an existing working suite and go on from there.

Thank you @RAc for the patient guidance!

Looking at the second PCAP, I do see checksum errors. You can see that if you enable checksum verification in WireShark: IP, UDP and TCP.

See WireShark:

Preferences -> Protocols -> IPv4 -> Validate the IPv4 checksum if possible
Preferences -> Protocols -> TCP -> Validate the TCP checksum if possible
Preferences -> Protocols -> UDP -> Validate the UDP checksum if possible

WireShark complains bout the Eth address 01:41:11:11:11:01

In the second PCAP I see this IP checksum error:

Header Checksum: 0x0000 incorrect, should be 0x59dc(may be caused by "IP checksum offload"?)

0x0000 normally means that it has not been set.

If I were you I would also use a simple program that is known to work well.
Also important to have an easy way for sending logging, something like:

    int udp_log (const char pcFormat, ...);

I wrote a telnet server called telnet.c. In telnet_usage.c you can check how to use it.

So you just call xSetupTelnet() once the network is up and running. That function will create a new task prvTelnetLoop(), which serves as the echo server.

The example uses port 23002, hardcoded.

But first make sure that your devices set the checksum properly.

Hi there htibosch,

thanks for following up!

I believe you may be on a wrong track, though. I did not see those checksum errors when I opened the pcap. Also, I believe that if there would have been checksum errors, they would have been swallowed by the peer - which means there would never have been responses to the SYN requests, but the presence of the RST packets in the trace are testimony to the fact that at least in the .1 to .3 scenario, the SYN packets have passed packet validation, or am I misinterpreting something?

Sorry, yes you’re right, checksum errors are only seen when the source IP address is x.x.x.3 (a HP laptop). Actually, the PCAP (“tcp client ip1 to server ip3port 10000”) looks all good.
The SYN is understood and the laptop answers that TCP port 10000 is not open.

In that case I would make sure that you device can easily send logging, for instance by sending UDP packets to the broadcast address 192.168.0.255 and listening by a UDP terminal.

You can find a UDP logging module called UDPLoggingPrintf.

And I would clear the broadcast/multicast bit in the MAC address:

-    01:41:11:11:11:01
+    00:41:11:11:11:01


Although I’m not sure if it makes a difference.

@mml You may want to look at this example - FreeRTOS/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleTCPEchoServer.c at main · FreeRTOS/FreeRTOS · GitHub.

Hi @aggarg
This is the project I use as a base one. I deviate from it because I don’t understand how some functions work. In this topic, my task is to establish a connection. Do not transmit data yet. Don’t disconnect yet.

I consider it necessary to explain why such a construction appeared, which was interpreted as incorrect.

do
		{
			xThisChildSocket = FreeRTOS_accept(xThisServerSocket, &xThatClientSocketAddress, sizeof( xThatClientSocketAddress ));
			configASSERT( xThisChildSocket != FREERTOS_INVALID_SOCKET );
			if (xThisChildSocket == 0)
			{
				#if (INFOINSHARK == 1)
				strcpy( WinInfoString, "Timeout FreeRTOS_accept");
				FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
				#endif
			}
			else
			{
				#if (INFOINSHARK == 1)
				strcpy( WinInfoString, "!!! xThisChildSocket have been got !!!");
				while(1){
					FreeRTOS_sendto(xSharkWinSocket, WinInfoString, strlen (WinInfoString), 0, &xSharkWinAddress, sizeof(xSharkWinAddress));
					vTaskDelay( pdTICKS_TO_MS( 1000 ) );
				}
				#endif
			}
			vTaskDelay( pdTICKS_TO_MS( 50 ) );
		}
		while (xThisChildSocket == 0);

In this code, I wait for the socket to be received and I will send UDP messages about it to .3 every second.
The fact is that the FreeRTOS_accept function returns an entity, which in the if statement is interpreted as 0. Such a return value corresponds to the timeout according to @FreeRTOS_accept() - FreeRTOS™

If I configure the portMAX_DELAY timeout period, the FreeRTOS_accept function never returns.
I think the pressing question now is:

Why does the FreeRTOS_accept function not issue a normal socket but is always blocked?

Better enclose code blocks by 3 tildes ‘~~~’ for readability.

Found a bug in my code.
Was:

FreeRTOS_bind( xThisServerSocket, 0, sizeof(xThisServerSocketAddress));

Right:

FreeRTOS_bind( xThisServerSocket, &xThisServerSocketAddress, 
sizeof(xThisServerSocketAddress));

Thank you for reporting back, @mml .