Jump to content
Форум по продукции MOXA

Проблема с удалением сокетов


Recommended Posts

Доброго времени суток!

Возникла проблема... управляющая программа - сервер, на IA240-LX не удаляет "мёртвые" соединения. А именно на PC с Debian  имеется программа - клиент, которая подключается к этому серверу и считывает данные из программы - сервера на IA240-LX. Тут проблем нет, но вот дополнительный скрипт на Debian контролирует состояние сервера на IA240-LX с помощью nc и при необходимости (разрыве и восстановлении связи) перезапускает локального клиента. Вот скрипт:

#!/bin/bash
#

#адрес утройства swc_moxa
_ipaddress_swc_moxa="192.168.0.232"
#порт устройства swc_moxa
_ipport_swc="8197"
#
_outdat="../log/start_swc.txt"

./swc.sh stop
((loop = 1))
while( ((loop > 0)) )
do
	str=$(nc -w1 -vvz $_ipaddress_swc_moxa $_ipport_swc 2>&1)
	str=$(echo -e "$str" | grep "open")
	sz=$(echo ${#str})
	if ( ((sz > 0)) ); then
		echo "программа SWC_MOXA запущена - проверяем SWC"
		str=$(nc -w1 -vvz 0.0.0.0 $_ipport_swc 2>&1)
		str=$(echo -e "$str" | grep "open")
		sz=$(echo ${#str})
		if ( ((sz > 0)) ); then
			echo "программа SWC запущена"
		else
			echo "запускаем SWC"
			./swc.sh stop
			ServerTime=$(date --date="now" +%d.%m.%Y" "%H:%M:%S)
			echo -e "Start Sistem Water Ccontrol: $ServerTime" >> $_outdat
			./swc.sh start
		fi
	else
		echo "нет доступа к программе SWC_MOXA - остановка SWC"
		ServerTime=$(date --date="now" +%d.%m.%Y" "%H:%M:%S)
		echo -e "Start Sistem Water Ccontrol: $ServerTime" >> $_outdat
		./swc.sh stop
	fi
	sleep 10
done

То есть на Debian перезапускает работу своего клиента. На IA240-LX программа-сервер в автозапуске. Собственно в консоли IA240-LX так:

www-data@Moxa:~$ netstat -nlta | grep 8197
tcp        0      0 0.0.0.0:8197            0.0.0.0:*               LISTEN      
tcp        0      0 192.168.0.232:8197      192.168.0.234:46867     SYN_RECV    
tcp        0      0 192.168.0.232:8197      192.168.0.234:46875     SYN_RECV    
tcp        0      0 192.168.0.232:8197      192.168.0.234:46871     SYN_RECV    
tcp        0      0 192.168.0.232:8197      192.168.0.234:46863     SYN_RECV    
tcp        0      0 192.168.0.232:8197      192.168.0.234:46859     SYN_RECV    
tcp        1      0 192.168.0.232:8197      192.168.0.234:46739     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46747     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46731     CLOSE_WAIT  
tcp        0      0 127.0.0.1:1027          127.0.0.1:8197          ESTABLISHED 
tcp        1      0 192.168.0.232:8197      192.168.0.234:46755     CLOSE_WAIT  
tcp     6664      0 192.168.0.232:8197      192.168.0.234:46729     ESTABLISHED 
tcp     9840      0 127.0.0.1:8197          127.0.0.1:1027          ESTABLISHED 
tcp        1      0 192.168.0.232:8197      192.168.0.234:46726     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46743     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46751     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46735     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46759     CLOSE_WAIT  
www-data@Moxa:~$ 

значения

tcp 0 0 192.168.0.232:8197 192.168.0.234:46867 SYN_RECV не беда

но вот

tcp 1 0 192.168.0.232:8197 192.168.0.234:46726 CLOSE_WAIT  отсаются висеть "пожизненоо"

 

Сервер на IA240 имеет ограничение в 10 клиентов. На устройстве имеется так же клиент для работы с даполнительным Modbus RTU(порт 2)

Об устроqстве IA240-LX:

www-data@Moxa:~$ uname -a
Linux Moxa 2.6.9-uc0 #4 Wed Jun 14 15:40:27 CST 2017 armv4tl unknown
www-data@Moxa:~$ 

Может что не так с устройством - аналогичный метод проверки работоспособности реализован и к UC-7101-LX - там проблем нет:

Код Listen сервера (уже добавил излишества... ну понятно почему):

void server_listen(void)
{
	int err;
        fd_set fdss;
        struct timeval tvs;
        int count;
        int csock;
	u_int8_t	work;
	//
	pthread_mutex_lock(&ServerMutex);
        //инициализация данных
        memset(&cserver.midcl[0], 0, _max_sock);
        cserver.cntclient 		= 0;
	cserver.setcntlive		= _stime_life;
	pthread_mutex_unlock(&ServerMutex);
	//основной цикл прослушивания
        while(work)
        {
		tvs.tv_sec = _LSOCKET_TIMEOUT_S;
                tvs.tv_usec = _LSOCKET_TIMEOUT_uS;
                FD_ZERO(&fdss);
                FD_SET(listener,&fdss);
                //
                err = select(listener + 1,&fdss,&fdss,NULL,&tvs);
                if(err <= 0)
                {
			pthread_mutex_lock(&ServerMutex);
			work	= cserver.work;
			pthread_mutex_unlock(&ServerMutex);
			usleep(_listen_sleep);
                        continue;
                }
                csock = accept(listener,NULL,NULL);
                if(!(csock > 0))
                {
			pthread_mutex_lock(&ServerMutex);
                        work	= cserver.work;
			pthread_mutex_unlock(&ServerMutex);
			shutdown(csock, SHUT_RDWR);
			close(csock);
			usleep(_listen_sleep);
                        continue;
                }
		//создание потока клиента
		pthread_mutex_lock(&ServerMutex);
		count	= cserver.cntclient;
                if(!(count < _max_sock))
		{
			shutdown(csock, SHUT_RDWR);
			close(csock);
			goto met2;
		}
                count = 0;
                while(count < _max_sock)
                {
                        if(cserver.midcl[count] == 0)
                        {
				#if(_dbg > 0)
					printf("ServCoon clien %i connecting...\n",count);
				#endif
                                cserver.csock	 		= csock;
                                cserver.idclient 		= count;
				cserver.midcl[count]		= 0xFF;
				//				
				pthread_attr_init(&cserver.tattr[count]);
				pthread_attr_setdetachstate(&cserver.tattr[count], PTHREAD_CREATE_DETACHED);
				pthread_create(&cserver.pth[count], &cserver.tattr[count],(void*) server_con, &cserver);
				//
                                cserver.cntclient++;
				break;
                        }
                        count++;
                }
                //
met2:		work	= cserver.work;
	        pthread_mutex_unlock(&ServerMutex);
                usleep(_listen_sleep);
        }
	pthread_exit(0); 
}

собственно поток работы с соединением( для сокета и shutdown, и close):

//поток клиента
void server_con(CSERV * cs)
{
	int		countlive;
	int		setcntlive;
	int		csock;
	int		idclient;
	//int		rd;
	//pthread_t	pth;
	u_int8_t	midcl;
	u_int8_t	rxbuf[_size_buf];
	u_int8_t	txbuf[_size_buf];
	int		txsz;
	u_int8_t	work;
	int		res;
	#if(_deb_con == 1)
		printf("ServConn client connected\n");
	#endif

	pthread_mutex_lock(&ServerMutex);

	countlive 	= cs->setcntlive;
	setcntlive	= cs->setcntlive;
	csock		= cs->csock;
	idclient	= cs->idclient;
	midcl		= cs->midcl[idclient];
	//pth		= cs->pth[idclient];
	work		= cs->work;
	//
	#if(_deb_con == 1)
		printf("swc_moxa server... client:%i connected and starting...\n", idclient);
	#endif
	//
	while(1)
	{
		#if(_deb_con > 0)
			printf("client:%i countlive: %i\n", idclient, countlive);
		#endif
		work		= cs->work;
		pthread_mutex_unlock(&ServerMutex);
		if(work == 0)
			break;
		//чтение сокета
		txsz = 0;
		memset(&rxbuf[0], 0, _size_buf);
		res = swcReadSocket(csock, &rxbuf[0]);
		switch(res)
		{
			case 0:	//Null
				goto mexit;
			case -1: //таймаут
				#if(_swc_deb_con == 1)
					printf("swc_moxa server... TCP recv. client:%i timeout..\r\n",idclient);
				#endif
				break;
			case -2: //какая-то ошибка сокета
				#if(_swc_deb_con == 1)
					printf("swc_moxa server... TCP resv. client:%i err?..\r\n",idclient);
				#endif
				goto mexit;
			case -3: //ошибка размера пакета
				//передача сообщения о несоответствии
				#if(_swc_deb_con == 1)
					printf("swc_moxa server... TCP recv. client:%i frame no correct..\r\n",idclient);
				#endif
				goto mexit; //отмена обработки запроса
			default: //нормально - данные приняты
				//countlive = setcntlive;
				//обработка команд и данных сокета
				#if(_swc_deb_con == 1)
					printf("swc_moxa server... TCP recv. client:%i starting mwork..\n",idclient);
				#endif
				memset(&txbuf[0], 0, _size_buf);
				txsz = mwork(&rxbuf[0], &txbuf[0]);
				break;
		}
		//передача данных
		if(txsz > 0)
		{
			res = swcWriteSocket(csock, &txbuf[0], txsz);
			switch(res)
			{
				case 0:
					#if(_swc_deb_con == 1)
						printf("swc_moxa server... TCP swnd.:%i null send..\r\n",idclient);
					#endif
					break;
				case -1:		//таймаут
					#if(_swc_deb_con == 1)
						printf("swc_moxa server... TCP send.:%i timeout..\r\n",idclient);
					#endif
					break;
				case -2:
					#if(_swc_deb_con == 1)
						printf("swc_moxa server... TCP send.:%i err?..\r\n",idclient);
					#endif
					goto mexit;
				default:
					countlive = setcntlive;
					break;
			}
		}
		//ожидание и новый цикл
		countlive--;
		if(!(countlive > 0)) //никому это соединение не нужно
			break;
		usleep(_conn_sleep);
		pthread_mutex_lock(&ServerMutex);
	}
mexit:	shutdown(csock, SHUT_RDWR);
	close(csock);
	pthread_mutex_lock(&ServerMutex);
	cs->midcl[idclient] = 0;
	cs->cntclient--;
	pthread_mutex_unlock(&ServerMutex);
	//return 0;
	pthread_exit(0); 
}

Честно сказать не первый день бьюсь... но не испытал на своём UC7112-Lx-Plus. Он для теста и разработки. И если скрипт контроля не запускать, то всё нормально... вот только на объекте электричество отключают не редко. А восстановить параметры некому.

Может что с версией прошивки не то? Поставил в проект из коробки, только SD карту поставил и примонтировал /usr, /home... пердварительно скопировав в них нужные файлы с устройства и даполнив своими (mc, nc,..)

С Глубоким Уважением!

Спасбо!

 

Link to comment

Доброго времени суток!

Возникла проблема... управляющая программа - сервер, на IA240-LX не удаляет "мёртвые" соединения. А именно на PC с Debian  имеется программа - клиент, которая подключается к этому серверу и считывает данные из программы - сервера на IA240-LX. Тут проблем нет, но вот дополнительный скрипт на Debian контролирует состояние сервера на IA240-LX с помощью nc и при необходимости (разрыве и восстановлении связи) перезапускает локального клиента. Вот скрипт:

#!/bin/bash
#

#адрес утройства swc_moxa
_ipaddress_swc_moxa="192.168.0.232"
#порт устройства swc_moxa
_ipport_swc="8197"
#
_outdat="../log/start_swc.txt"

./swc.sh stop
((loop = 1))
while( ((loop > 0)) )
do
	str=$(nc -w1 -vvz $_ipaddress_swc_moxa $_ipport_swc 2>&1)
	str=$(echo -e "$str" | grep "open")
	sz=$(echo ${#str})
	if ( ((sz > 0)) ); then
		echo "программа SWC_MOXA запущена - проверяем SWC"
		str=$(nc -w1 -vvz 0.0.0.0 $_ipport_swc 2>&1)
		str=$(echo -e "$str" | grep "open")
		sz=$(echo ${#str})
		if ( ((sz > 0)) ); then
			echo "программа SWC запущена"
		else
			echo "запускаем SWC"
			./swc.sh stop
			ServerTime=$(date --date="now" +%d.%m.%Y" "%H:%M:%S)
			echo -e "Start Sistem Water Ccontrol: $ServerTime" >> $_outdat
			./swc.sh start
		fi
	else
		echo "нет доступа к программе SWC_MOXA - остановка SWC"
		ServerTime=$(date --date="now" +%d.%m.%Y" "%H:%M:%S)
		echo -e "Start Sistem Water Ccontrol: $ServerTime" >> $_outdat
		./swc.sh stop
	fi
	sleep 10
done

То есть на Debian перезапускает работу своего клиента. На IA240-LX программа-сервер в автозапуске. Собственно в консоли IA240-LX так:

www-data@Moxa:~$ netstat -nlta | grep 8197
tcp        0      0 0.0.0.0:8197            0.0.0.0:*               LISTEN      
tcp        0      0 192.168.0.232:8197      192.168.0.234:46867     SYN_RECV    
tcp        0      0 192.168.0.232:8197      192.168.0.234:46875     SYN_RECV    
tcp        0      0 192.168.0.232:8197      192.168.0.234:46871     SYN_RECV    
tcp        0      0 192.168.0.232:8197      192.168.0.234:46863     SYN_RECV    
tcp        0      0 192.168.0.232:8197      192.168.0.234:46859     SYN_RECV    
tcp        1      0 192.168.0.232:8197      192.168.0.234:46739     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46747     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46731     CLOSE_WAIT  
tcp        0      0 127.0.0.1:1027          127.0.0.1:8197          ESTABLISHED 
tcp        1      0 192.168.0.232:8197      192.168.0.234:46755     CLOSE_WAIT  
tcp     6664      0 192.168.0.232:8197      192.168.0.234:46729     ESTABLISHED 
tcp     9840      0 127.0.0.1:8197          127.0.0.1:1027          ESTABLISHED 
tcp        1      0 192.168.0.232:8197      192.168.0.234:46726     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46743     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46751     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46735     CLOSE_WAIT  
tcp        1      0 192.168.0.232:8197      192.168.0.234:46759     CLOSE_WAIT  
www-data@Moxa:~$ 

Сервер на IA240 имеет ограничение в 10 клиентов. На устройстве имеется так же клиент для работы с даполнительным Modbus RTU(порт 2)

Об устроqстве IA240-LX:

www-data@Moxa:~$ uname -a
Linux Moxa 2.6.9-uc0 #4 Wed Jun 14 15:40:27 CST 2017 armv4tl unknown
www-data@Moxa:~$ 

Может что не так с устройством - аналогичный метод проверки работоспособности реализован и к UC-7101-LX - там проблем нет:

Код Listen сервера (уже добавил излишества... ну понятно почему):

void server_listen(void)
{
	int err;
        fd_set fdss;
        struct timeval tvs;
        int count;
        int csock;
	u_int8_t	work;
	//
	pthread_mutex_lock(&ServerMutex);
        //инициализация данных
        memset(&cserver.midcl[0], 0, _max_sock);
        cserver.cntclient 		= 0;
	cserver.setcntlive		= _stime_life;
	pthread_mutex_unlock(&ServerMutex);
	//основной цикл прослушивания
        while(work)
        {
		tvs.tv_sec = _LSOCKET_TIMEOUT_S;
                tvs.tv_usec = _LSOCKET_TIMEOUT_uS;
                FD_ZERO(&fdss);
                FD_SET(listener,&fdss);
                //
                err = select(listener + 1,&fdss,&fdss,NULL,&tvs);
                if(err <= 0)
                {
			pthread_mutex_lock(&ServerMutex);
			work	= cserver.work;
			pthread_mutex_unlock(&ServerMutex);
			usleep(_listen_sleep);
                        continue;
                }
                csock = accept(listener,NULL,NULL);
                if(!(csock > 0))
                {
			pthread_mutex_lock(&ServerMutex);
                        work	= cserver.work;
			pthread_mutex_unlock(&ServerMutex);
			shutdown(csock, SHUT_RDWR);
			close(csock);
			usleep(_listen_sleep);
                        continue;
                }
		//создание потока клиента
		pthread_mutex_lock(&ServerMutex);
		count	= cserver.cntclient;
                if(!(count < _max_sock))
		{
			shutdown(csock, SHUT_RDWR);
			close(csock);
			goto met2;
		}
                count = 0;
                while(count < _max_sock)
                {
                        if(cserver.midcl[count] == 0)
                        {
				#if(_dbg > 0)
					printf("ServCoon clien %i connecting...\n",count);
				#endif
                                cserver.csock	 		= csock;
                                cserver.idclient 		= count;
				cserver.midcl[count]		= 0xFF;
				//				
				pthread_attr_init(&cserver.tattr[count]);
				pthread_attr_setdetachstate(&cserver.tattr[count], PTHREAD_CREATE_DETACHED);
				pthread_create(&cserver.pth[count], &cserver.tattr[count],(void*) server_con, &cserver);
				//
                                cserver.cntclient++;
				break;
                        }
                        count++;
                }
                //
met2:		work	= cserver.work;
	        pthread_mutex_unlock(&ServerMutex);
                usleep(_listen_sleep);
        }
	pthread_exit(0); 
}

собственно поток работы с соединением( для сокета и shutdown, и close):

//поток клиента
void server_con(CSERV * cs)
{
	int		countlive;
	int		setcntlive;
	int		csock;
	int		idclient;
	//int		rd;
	//pthread_t	pth;
	u_int8_t	midcl;
	u_int8_t	rxbuf[_size_buf];
	u_int8_t	txbuf[_size_buf];
	int		txsz;
	u_int8_t	work;
	int		res;
	#if(_deb_con == 1)
		printf("ServConn client connected\n");
	#endif

	pthread_mutex_lock(&ServerMutex);

	countlive 	= cs->setcntlive;
	setcntlive	= cs->setcntlive;
	csock		= cs->csock;
	idclient	= cs->idclient;
	midcl		= cs->midcl[idclient];
	//pth		= cs->pth[idclient];
	work		= cs->work;
	//
	#if(_deb_con == 1)
		printf("swc_moxa server... client:%i connected and starting...\n", idclient);
	#endif
	//
	while(1)
	{
		#if(_deb_con > 0)
			printf("client:%i countlive: %i\n", idclient, countlive);
		#endif
		work		= cs->work;
		pthread_mutex_unlock(&ServerMutex);
		if(work == 0)
			break;
		//чтение сокета
		txsz = 0;
		memset(&rxbuf[0], 0, _size_buf);
		res = swcReadSocket(csock, &rxbuf[0]);
		switch(res)
		{
			case 0:	//Null
				goto mexit;
			case -1: //таймаут
				#if(_swc_deb_con == 1)
					printf("swc_moxa server... TCP recv. client:%i timeout..\r\n",idclient);
				#endif
				break;
			case -2: //какая-то ошибка сокета
				#if(_swc_deb_con == 1)
					printf("swc_moxa server... TCP resv. client:%i err?..\r\n",idclient);
				#endif
				goto mexit;
			case -3: //ошибка размера пакета
				//передача сообщения о несоответствии
				#if(_swc_deb_con == 1)
					printf("swc_moxa server... TCP recv. client:%i frame no correct..\r\n",idclient);
				#endif
				goto mexit; //отмена обработки запроса
			default: //нормально - данные приняты
				//countlive = setcntlive;
				//обработка команд и данных сокета
				#if(_swc_deb_con == 1)
					printf("swc_moxa server... TCP recv. client:%i starting mwork..\n",idclient);
				#endif
				memset(&txbuf[0], 0, _size_buf);
				txsz = mwork(&rxbuf[0], &txbuf[0]);
				break;
		}
		//передача данных
		if(txsz > 0)
		{
			res = swcWriteSocket(csock, &txbuf[0], txsz);
			switch(res)
			{
				case 0:
					#if(_swc_deb_con == 1)
						printf("swc_moxa server... TCP swnd.:%i null send..\r\n",idclient);
					#endif
					break;
				case -1:		//таймаут
					#if(_swc_deb_con == 1)
						printf("swc_moxa server... TCP send.:%i timeout..\r\n",idclient);
					#endif
					break;
				case -2:
					#if(_swc_deb_con == 1)
						printf("swc_moxa server... TCP send.:%i err?..\r\n",idclient);
					#endif
					goto mexit;
				default:
					countlive = setcntlive;
					break;
			}
		}
		//ожидание и новый цикл
		countlive--;
		if(!(countlive > 0)) //никому это соединение не нужно
			break;
		usleep(_conn_sleep);
		pthread_mutex_lock(&ServerMutex);
	}
mexit:	shutdown(csock, SHUT_RDWR);
	close(csock);
	pthread_mutex_lock(&ServerMutex);
	cs->midcl[idclient] = 0;
	cs->cntclient--;
	pthread_mutex_unlock(&ServerMutex);
	//return 0;
	pthread_exit(0); 
}

Честно сказать не первый день бьюсь... но не испытал на своём UC7112-Lx-Plus. Он для теста и разработки. И если скрипт контроля не запускать, то всё нормально... вот только на объекте электричество отключают не редко. А восстановить параметры некому.

Может что с версией прошивки не то? Поставил в проект из коробки, только SD карту поставил и примонтировал /usr, /home... пердварительно скопировав в них нужные файлы с устройства и даполнив своими (mc, nc,..)

С Глубоким Уважением!

Спасбо!

 

Простите! Вот глупость сморозил:

NetCat в мирных целях? :D

Ухожу на PING... Жаль конечно :(. NC более пригоден.

 

Но как уйти от этого:

значения

tcp 0 0 192.168.0.232:8197 192.168.0.234:46867 SYN_RECV не беда

но вот

tcp 1 0 192.168.0.232:8197 192.168.0.234:46726 CLOSE_WAIT  отсаются висеть "пожизненно"

Link to comment

Доброго времени суток!

Но вот вопрос:

Почему всё-таки на UC-7101-Lx (с uCLinux) нормально работает с применением NetCat (аналогично приведённому выше) - прошли сутки

# netstat -nlta | grep 8971
tcp        0      0 0.0.0.0:8971            0.0.0.0:*               LISTEN      
tcp        0      0 192.168.0.246:8971      192.168.0.234:36726     ESTABLISHED 
# 

, а на IA240-LX и UC7112-LX-Plus как говорил выше.

Неужели потму, что UC7101-LX работает от ROOT, а IA240-LX и UC7112-LX-Plus от www-data? Или uCLinux более отработана(обкатана) чем Linux конкретно для указанных устройств?

На UC7101-LX контроль ведётся за сервером modbusRTUserverS(знаю, что он кривой - работаю), а на IA240-LX и UC7112-LX-Plus за другим сервером управления. Программы делал аналогично.

Или важно что от ROOT? Может какие конфиги в /etc надо доплить?

Уж больно удобно проверять по NetCat состояние программы.

Если можете помогите!

Спасибо!

Link to comment
  • 2 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...