空闲一段时间后无法连接到lwip绑定的套接字地址

时间:2015-02-07 16:23:23

标签: sockets tcp freertos lwip

我在FreeRTOS下使用lwIP,IP服务器在基于ARM的设备(Xilinx Zynq-7020)上运行,客户端是Windows。

在服务器端,当我绑定,监听并接受地址:端口时,客户端可以连接到该地址并从该地址读取/写入。程序退出后,空闲一段时间(10s~30s)然后重新启动,它也可以从服务器读/写。但是,当我退出客户端并闲置很长时间(> 30秒)时,我无法再连接到服务器了。在服务器端,它不再接受任何地址。任何解决方案?

服务器端的代码如下:

void echo_server( void *pvParameters )
{

    long lSocket, lClientFd, lAddrLen = sizeof( struct sockaddr_in );
    struct sockaddr_in sLocalAddr;
    struct sockaddr_in client_addr;

    static char dIn[BUF_SIZE];
    int ret;
    ( void ) pvParameters;

    int on = 1;
    int idle = 60;
    int intvl = 15;
    int cnt = 3;

    /* step 1. create and setopts */
    lSocket = lwip_socket(AF_INET, SOCK_STREAM, 0);

    if( lSocket >= 0 )
    {
        lwip_setsockopt(lSocket, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
        //lwip_setsockopt(lSocket, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));
        //lwip_setsockopt(lSocket, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl));
        //lwip_setsockopt(lSocket, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));

        memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));

        // prepare bind on port
        sLocalAddr.sin_family = AF_INET;
        sLocalAddr.sin_len = sizeof(sLocalAddr);
        sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        sLocalAddr.sin_port = ntohs( ( ( unsigned short ) ECHO_PORT ) );

        /* step 2. bind */
        if( lwip_bind( lSocket, ( struct sockaddr *) &sLocalAddr, sizeof( sLocalAddr ) ) < 0 )
        {
            lwip_close( lSocket );
            vTaskDelete( NULL );
        }

        /* step 3. listen */
        if( lwip_listen( lSocket, BACKLOG ) != 0 )
        {
            lwip_close( lSocket );
            vTaskDelete( NULL );
        }

        for( ;; )
        {

            /* step 4. accept */
            xil_printf("(ZYNQ-ECH) wait connection\n");
            lClientFd = lwip_accept(lSocket, ( struct sockaddr * ) &client_addr, ( u32_t * ) &lAddrLen );
            xil_printf("(ZYNQ-ECH) accept connection\n");

            lwip_setsockopt(lClientFd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on));
            //lwip_setsockopt(lClientFd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));
            //lwip_setsockopt(lClientFd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl));
            //lwip_setsockopt(lClientFd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));

            // if client socket created
            if( lClientFd > 0L )
            {

                int packet = 0;
                while(1)
                {

                    ret = mfeit_read(lClientFd, dIn);
                    if (ret == -1 || ret == 0)
                        break;

                    ret = mfeit_write( lClientFd, dIn, ret );
                    if (ret == -1 || ret == 0)
                        break;

                    packet ++;

                }
                xil_printf("(ZYNQ-ECH) close connection, total = %d\n", packet);
                lwip_close( lClientFd );
            }
        }
    }

    /* Will only get here if a listening socket could not be created. */
    xil_printf("(ZYNQ-ECH) task killed !!\n");
    vTaskDelete( NULL );
}

1 个答案:

答案 0 :(得分:0)

我忘记了那些东西,但首先你需要建立适当的保持活力的方式。

  1. 在配置的服务器上保持活动状态,因此他持续存活多久

  2. 为你保持活着的适当时间。

  3. 不要在2小时或某些时间保持活力。为服务器资源创建一个新的套接字。