enum pubnub_res pbpal_resolv_and_connect(pubnub_t *pb)
{
    struct freertos_sockaddr addr;

    PUBNUB_ASSERT(pb_valid_ctx_ptr(pb));
    PUBNUB_ASSERT_OPT((pb->state == PBS_IDLE) || (pb->state == PBS_WAIT_DNS));
    
    addr.sin_port = FreeRTOS_htons(HTTP_PORT);
    addr.sin_addr = FreeRTOS_gethostbyname(PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN);
    if (addr.sin_addr == 0) {
        return PNR_CONNECT_FAILED;
    }

    pb->pal.socket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP);
    if (pb->pal.socket == SOCKET_INVALID) {
        return PNR_CONNECT_FAILED;
    }
    if (FreeRTOS_connect(pb->pal.socket, &addr, sizeof addr) != 0) {
        FreeRTOS_closesocket(pb->pal.socket);
        pb->pal.socket = SOCKET_INVALID;
        return PNR_CONNECT_FAILED;
    }

    {
        TickType_t tmval = pdMS_TO_TICKS(pb->transaction_timeout_ms);
        FreeRTOS_setsockopt(pb->pal.socket, 0, FREERTOS_SO_RCVTIMEO, &tmval, sizeof tmval);
    }

    return PNR_OK;
}
int ICACHE_FLASH_ATTR NetworkConnect(Network* n, char* addr, int port) {
    struct sockaddr_in sAddr;
    int retVal = -1;

    bzero(&sAddr, sizeof(struct sockaddr_in));
    if (!getIpForHost(addr, &sAddr)) {
        printf("get ip by hostname fail\n");
        return -1;
    }

    sAddr.sin_port = FreeRTOS_htons(port);

    if ((n->my_socket = FreeRTOS_socket(PF_INET, FREERTOS_SOCK_STREAM, 0)) < 0)
        goto exit;

//	printf("Connecting to server %s...\n", ipaddr_ntoa((const ip_addr_t*)&sAddr.sin_addr.s_addr));

    if ((retVal = FreeRTOS_connect(n->my_socket, (struct sockaddr * )(&sAddr),
                                   sizeof(struct sockaddr))) < 0) {
        FreeRTOS_closesocket(n->my_socket);
        goto exit;
    }

exit:
//	printf("------------>connect init: %d, sock:%d \n", retVal, n->my_socket);
    return retVal;

#if 0
    struct freertos_sockaddr sAddr;
    int retVal = -1;
    uint32_t ipAddress;
    struct sockaddr_in *name_in;

    struct ip_addr *ad;
    struct hostent *pHost;
    if ((pHost = FreeRTOS_gethostbyname(addr)) == 0)
        goto exit;

    ad = (struct ip_addr *)&pHost->h_addr_list[0];
    ipAddress = ad->addr;

    sAddr.sa_family = AF_INET;
    name_in = (struct sockaddr_in *)(void*)(&sAddr);
    name_in->sin_port = FreeRTOS_htons(port);
    name_in->sin_addr.s_addr = ipAddress;
    printf("----->get ip: %08x, %08x, %08x\n", ipAddress, port, FreeRTOS_htons(port));

    if ((n->my_socket = FreeRTOS_socket(FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP)) < 0)
        goto exit;

    printf("++++++++++>get ip: %s\n", addr);

    if ((retVal = FreeRTOS_connect(n->my_socket, &sAddr, sizeof(sAddr))) < 0)
    {
        FreeRTOS_closesocket(n->my_socket);
        goto exit;
    }

exit:
    printf("------------>connect init fail \n");
    return retVal;
#endif

#if 0
    int type = SOCK_STREAM;
    struct sockaddr_in address;
    int retVal = -1;
    sa_family_t family = AF_INET;
    struct addrinfo *result = NULL;
    struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL};

    if ((retVal = getaddrinfo(addr, NULL, &hints, &result)) == 0)
    {
        printf("------------------->1\n");
        struct addrinfo* res = result;
        /* prefer ip4 addresses */
        while (res)
        {
            if (res->ai_family == AF_INET)
            {
                result = res;
                break;
            }
            res = res->ai_next;
        }
        if (result->ai_family == AF_INET)
        {
            address.sin_port = htons(port);
            address.sin_family = family = AF_INET;
            address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr;
            printf("------------------->2, %08x, %08x\n", address.sin_port, address.sin_addr);
        }
        else
            retVal = -1;

        freeaddrinfo(result);
    }

    if (retVal == 0) {
        printf("------------------->3\n");
        n->my_socket = socket(family, type, 0);
        if (n->my_socket != -1) {
            printf("Connecting to server %s...\n", ipaddr_ntoa((const ip_addr_t*)&address.sin_addr.s_addr));
            printf("------------------->4, socket:%d\n", n->my_socket);
            while (1) {
                retVal = FreeRTOS_connect(n->my_socket, (struct sockaddr*)&address, sizeof(struct sockaddr));
                if (retVal == 0) break;
            }
            printf("------------------->5, retrun:%d\n", retVal);
        }
    }

exit:
    return retVal;
#endif
}
static void prvEchoClientTask( void *pvParameters )
{
Socket_t xSocket;
struct freertos_sockaddr xEchoServerAddress;
int32_t lLoopCount = 0UL;
const int32_t lMaxLoopCount = 1;
volatile uint32_t ulTxCount = 0UL;
BaseType_t xReceivedBytes, xReturned, xInstance;
BaseType_t lTransmitted, lStringLength;
char *pcTransmittedString, *pcReceivedString;
WinProperties_t xWinProps;
TickType_t xTimeOnEntering;

	/* Fill in the buffer and window sizes that will be used by the socket. */
	xWinProps.lTxBufSize = 6 * ipconfigTCP_MSS;
	xWinProps.lTxWinSize = 3;
	xWinProps.lRxBufSize = 6 * ipconfigTCP_MSS;
	xWinProps.lRxWinSize = 3;

	/* This task can be created a number of times.  Each instance is numbered
	to enable each instance to use a different Rx and Tx buffer.  The number is
	passed in as the task's parameter. */
	xInstance = ( BaseType_t ) pvParameters;

	/* Point to the buffers to be used by this instance of this task. */
	pcTransmittedString = &( cTxBuffers[ xInstance ][ 0 ] );
	pcReceivedString = &( cRxBuffers[ xInstance ][ 0 ] );

	/* Echo requests are sent to the echo server.  The address of the echo
	server is configured by the constants configECHO_SERVER_ADDR0 to
	configECHO_SERVER_ADDR3 in FreeRTOSConfig.h. */
	xEchoServerAddress.sin_port = FreeRTOS_htons( echoECHO_PORT );
	xEchoServerAddress.sin_addr = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0,
															configECHO_SERVER_ADDR1,
															configECHO_SERVER_ADDR2,
															configECHO_SERVER_ADDR3 );

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

		/* Set a time out so a missing reply does not cause the task to block
		indefinitely. */
		FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
		FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );

		/* Set the window and buffer sizes. */
		FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps,	sizeof( xWinProps ) );

		/* Connect to the echo server. */
		if( FreeRTOS_connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ) == 0 )
		{
			ulConnections[ xInstance ]++;

			/* Send a number of echo requests. */
			for( lLoopCount = 0; lLoopCount < lMaxLoopCount; lLoopCount++ )
			{
				/* Create the string that is sent to the echo server. */
				lStringLength = prvCreateTxData( pcTransmittedString, echoBUFFER_SIZES );

				/* Add in some unique text at the front of the string. */
				sprintf( pcTransmittedString, "TxRx message number %u", ulTxCount );
				ulTxCount++;

				/* Send the string to the socket. */
				lTransmitted = FreeRTOS_send(	xSocket,						/* The socket being sent to. */
												( void * ) pcTransmittedString,	/* The data being sent. */
												lStringLength,					/* The length of the data being sent. */
												0 );							/* No flags. */

				if( lTransmitted < 0 )
				{
					/* Error? */
					break;
				}

				/* Clear the buffer into which the echoed string will be
				placed. */
				memset( ( void * ) pcReceivedString, 0x00, echoBUFFER_SIZES );
				xReceivedBytes = 0;

				/* Receive data echoed back to the socket. */
				while( xReceivedBytes < lTransmitted )
				{
					xReturned = FreeRTOS_recv( xSocket,								/* The socket being received from. */
											&( pcReceivedString[ xReceivedBytes ] ),/* The buffer into which the received data will be written. */
											 lStringLength - xReceivedBytes,		/* The size of the buffer provided to receive the data. */
											 0 );									/* No flags. */

					if( xReturned < 0 )
					{
						/* Error occurred.  Latch it so it can be detected
						below. */
						xReceivedBytes = xReturned;
						break;
					}
					else if( xReturned == 0 )
					{
						/* Timed out. */
						break;
					}
					else
					{
						/* Keep a count of the bytes received so far. */
						xReceivedBytes += xReturned;
					}
				}

				/* If an error occurred it will be latched in xReceivedBytes,
				otherwise xReceived bytes will be just that - the number of
				bytes received from the echo server. */
				if( xReceivedBytes > 0 )
				{
					/* Compare the transmitted string to the received string. */
					configASSERT( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 );
					if( strncmp( pcReceivedString, pcTransmittedString, lTransmitted ) == 0 )
					{
						/* The echo reply was received without error. */
						ulTxRxCycles[ xInstance ]++;
					}
					else
					{
						/* The received string did not match the transmitted
						string. */
						ulTxRxFailures[ xInstance ]++;
						break;
					}
				}
				else if( xReceivedBytes < 0 )
				{
					/* FreeRTOS_recv() returned an error. */
					break;
				}
				else
				{
					/* Timed out without receiving anything? */
					break;
				}
			}

			/* Finished using the connected socket, initiate a graceful close:
			FIN, FIN+ACK, ACK. */
			FreeRTOS_shutdown( xSocket, FREERTOS_SHUT_RDWR );

			/* Expect FreeRTOS_recv() to return an error once the shutdown is
			complete. */
			xTimeOnEntering = xTaskGetTickCount();
			do
			{
				xReturned = FreeRTOS_recv( xSocket,	/* The socket being received from. */
					&( pcReceivedString[ 0 ] ),		/* The buffer into which the received data will be written. */
					echoBUFFER_SIZES,				/* The size of the buffer provided to receive the data. */
					0 );

				if( xReturned < 0 )
				{
					break;
				}

			} while( ( xTaskGetTickCount() - xTimeOnEntering ) < xReceiveTimeOut );
		}

		/* Close this socket before looping back to create another. */
		FreeRTOS_closesocket( xSocket );

		/* Pause for a short while to ensure the network is not too
		congested. */
		vTaskDelay( echoLOOP_DELAY );
	}
}