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

Sockets 空闲一段时间后无法连接到lwip绑定的套接字地址,sockets,tcp,freertos,lwip,Sockets,Tcp,Freertos,Lwip,我在FreeRTOS下使用lwIP,IP服务器运行在基于ARM的设备(Xilinx Zynq-7020)上,客户端是windows 在服务器端,当我绑定、侦听和接受一个地址:port时,客户端可以连接到该地址并从该地址读/写。程序退出后,空闲一段时间(10s~30s),然后重新启动,也可以从服务器读/写。但是,当我退出客户机,并且空闲了很长时间(>30秒),我就无法再连接到服务器。在服务器端,它不再接受任何地址。有什么解决办法吗 服务器端的代码如下所示: void echo_server( vo

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

在服务器端,当我绑定、侦听和接受一个地址:port时,客户端可以连接到该地址并从该地址读/写。程序退出后,空闲一段时间(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 );
}
void echo_服务器(void*pvParameters)
{
长lSocket,lClientFd,lAddrLen=sizeof(结构sockaddr\u in);
sLocalAddr中的结构sockaddr\u;
客户端地址中的结构sockaddr\u;
静态字符dIn[BUF_大小];
int ret;
(void)pvc参数;
int on=1;
int怠速=60;
int intvl=15;
int-cnt=3;
/*步骤1.创建和设置选项*/
lSocket=lwip\u套接字(AF\u INET,SOCK\u STREAM,0);
如果(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_keepnt和cnt、sizeof(cnt));
memset((char*)&sLocalAddr,0,sizeof(sLocalAddr));
//在端口上准备绑定
sLocalAddr.sin_family=AF_INET;
sLocalAddr.sin_len=sizeof(sLocalAddr);
sLocalAddr.sin\u addr.s\u addr=htonl(不包含任何内容);
sLocalAddr.sin_port=ntohs((无符号短)ECHO_port));
/*步骤2.绑定*/
if(lwip_bind(lSocket,(struct sockaddr*)和sLocalAddr,sizeof(sLocalAddr))<0
{
lwip_关闭(lSocket);
vTaskDelete(空);
}
/*第三步,听*/
如果(lwip_侦听(lSocket,BACKLOG)!=0)
{
lwip_关闭(lSocket);
vTaskDelete(空);
}
对于(;;)
{
/*步骤4.接受*/
xil_printf(“ZYNQ-ECH)等待连接\n”);
lClientFd=lwip_accept(lSocket,(struct sockaddr*)和client_addr,(u32_t*)和lAddrLen);
xil_printf(“ZYNQ-ECH)接受连接\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_keepnt和cnt、sizeof(cnt));
//如果客户端套接字已创建
如果(lClientFd>0L)
{
int包=0;
而(1)
{
ret=mfeit_读取(lClientFd,dIn);
如果(ret==1 | | ret==0)
打破
ret=mfeit_写入(lClientFd、dIn、ret);
如果(ret==1 | | ret==0)
打破
包++;
}
xil_printf(((ZYNQ-ECH)紧密连接,总数=%d\n”,数据包);
lwip_关闭(lClientFd);
}
}
}
/*仅当无法创建侦听套接字时才会到达此处*/
xil_printf(“(ZYNQ-ECH)任务已被杀死!!\n”);
vTaskDelete(空);
}

我忘了那些东西,但首先你需要设置适当的方式来保持活力

  • 服务器上是否配置了keep alive,那么他将保持keep alive多长时间

  • 设定适当的时间让你保持活力

  • 不要用2小时或其他什么来维持生命。创建一个新的套接字,因为它不利于服务器资源


  • 您好,我尝试使用不同的选项保持活动状态,例如
    inton=1;无符号整数空闲=7200;//以秒为单位,无符号整数intvl=3600;//以秒为单位,无符号整数cnt=9;lwip_setsockopt(socket、SOL_socket、SO_KEEPALIVE和on、sizeof(on));lwip_setsockopt(套接字、SOL_套接字、TCP_KEEPIDLE(void*)和idle、sizeof(idle));lwip_setsockopt(套接字、SOL_套接字、TCP_KEEPINTVL(void*)和intvl、sizeof(intvl));lwip_setsockopt(套接字、SOL_套接字、TCP_keepnt(void*)和cnt、sizeof(cnt))它们都不起作用。我在谷歌上搜索发现,MAC地址可能是我手动设置MAC地址的问题。(续)MAC地址为00-13-14-15-15-16,并通过路由器将lwip应用程序路由到PC,这可能是问题吗?嗯,MAC可能是问题,但您是否通过WireShark()或其他方式检查了网络上的情况?将其直接连接到您的PC LAN中,然后查看发生了什么。KEEP_ALIVE数据包将被发送,如果不超过设备上的问题,如果它们被发送,则服务器不接受KEEP ALIVE(我认为它必须被配置,不确定)。