Я использую lwIP под FreeRTOS, IP-сервер работает на устройстве на базе ARM (Xilinx Zynq-7020), а клиент - это Windows.
На стороне сервера, когда я привязываю, слушаю и принимаю адрес: порт, клиент может подключаться и читать / писать с этого адреса. И после выхода из программы, простоя в течение короткого времени (10 ~ 30 секунд), затем запускается снова, он также может читать / писать с сервера. Однако, когда я выхожу из клиента и долгое время простаиваю (> 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 );
}