реклама на сайте
подробности

 
 
> Закрытие и открытие сокета TCP - как правильно?, Keil 4.72 стек Keil (STM32F107)
smk
сообщение Aug 8 2014, 10:20
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



При изменении номера порта требуется пересоздать сокет. При этом у меня получается что после смены порта коннект возможен как по старому номеру порта так и по новому номеру. Если котнроллер перегрузить то тогда соединение возможно только по новому значению порта. Отсюда вопрос как правильно закрыть/открыть сокет чтобы соединение было возможно только по новому значению номера порта.

Получаем новое значение номера ставим флаг:
Код
        PortNumber  = s[0];
        Flags.ChangePort = 1;


обрабатываем флаг:
Код
if(Flags.ChangePort)
    {
        poll_socket (SocketNumber);
        disconnect_tcp (SocketNumber);
        SetSocket ();
        Flags.ChangePort = 0;
    }


Код
void SetSocket (void)
{
    
    SocketNumber = tcp_get_socket (TCP_TYPE_SERVER | TCP_TYPE_DELAY_ACK | TCP_TYPE_FLOW_CTRL | TCP_TYPE_KEEP_ALIVE, 0, 65535, tcp_callback);

    
    if (SocketNumber != 0)
        {
            /* Start listening on TCP port DevEthInfo.CtrlPort */
            tcp_listen (SocketNumber, PortNumber);
        }    
}

void disconnect_tcp (U8 tcp_soc)
{
  
  /* This TCP connection is no longer needed */
  tcp_close (tcp_soc);
  /* Release TCP Socket in a polling function */
}

void poll_socket (U8 tcp_soc)
{
  int state;

  state = tcp_get_state (tcp_soc);
  if (state > TCP_STATE_LISTEN)
        {
    /* Closing procedure is on-going */
    return;
        }
  if (state == TCP_STATE_LISTEN)
        {
    /* Socket has TCP_TYPE_SERVER attribute */
    /* needs additional close request.      */
    tcp_close (tcp_soc);
        }
  /* A socket is in TCP_STATE_CLOSED state now. */
  tcp_release_socket (tcp_soc);
}


И еще такой вопрос.

Код
unsigned char remip[4] = {192,168,0,1};


IP адрес для клиента закрываемого соединения где брать?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 6)
Golikov A.
сообщение Aug 8 2014, 12:39
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



сокет надо закрывать двойным вызовом close
Однократный вызов переводи открытый сокет в листен мод, а второй его закроет...

When a socket type is TCP_TYPE_SERVER or TCP_TYPE_CLIENT_SERVER, the socket does not close after calling tcp_close. The active connection is closed, and the socket transits to TCP_STATE_LISTEN. In this state, the socket is still able to accept incoming connections. To close the TCP_TYPE_SERVER socket, the function tcp_close needs to be called twice.

еще из коментов к коду у вас
Код
tcp_get_socket (TCP_TYPE_SERVER | TCP_TYPE_DELAY_ACK | TCP_TYPE_FLOW_CTRL | TCP_TYPE_KEEP_ALIVE, 0, 65535, tcp_callback);


вот эти 65535 - это время между проверками что соединение живо TCP_TYPE_KEEP_ALIVE и вы не поверите, но оно в секундах,
то есть как у вас сокет будет проверять себя на жизнеспособность примерно 1 раз в 18 часов, то есть фактически никогда. Так что этот флаг вам мало поможетsm.gif. Если его убрать то это время авто закрытия сокета по бездействию, тогда чем больше тем оно конечно лучше...


Цитата
IP адрес для клиента закрываемого соединения где брать?

я так понимаю сохранять при открытии соединения... А зачем оно вам надо?
Go to the top of the page
 
+Quote Post
smk
сообщение Aug 8 2014, 13:45
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



два раза и закрываю. может следует ждать пока случится state == TCP_STATE_LISTEN?

Код
void poll_socket (U8 tcp_soc)
{
  int state;
  tcp_close (tcp_soc);
    
  state = tcp_get_state (tcp_soc);
  if (state > TCP_STATE_LISTEN)
        {
    /* Closing procedure is on-going */
    return;
        }
  if (state == TCP_STATE_LISTEN)
        {
    /* Socket has TCP_TYPE_SERVER attribute */
    /* needs additional close request.      */
    tcp_close (tcp_soc);
        }
  /* A socket is in TCP_STATE_CLOSED state now. */
  tcp_release_socket (tcp_soc);
}


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 8 2014, 16:41
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



может быть, в примере вон ждут... процедура закрытия сокета долгая, там же обмен посылками идет....
Go to the top of the page
 
+Quote Post
smk
сообщение Aug 8 2014, 18:47
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(Golikov A. @ Aug 8 2014, 19:41) *
может быть, в примере вон ждут... процедура закрытия сокета долгая, там же обмен посылками идет....

а как в примере ждут? есть кусок кода?
если я правильно понял то
Код
state = tcp_get_state (tcp_soc);

изменится только по истечении
Код
SocketNumber = tcp_get_socket (TCP_TYPE_SERVER | TCP_TYPE_DELAY_ACK | TCP_TYPE_FLOW_CTRL | TCP_TYPE_KEEP_ALIVE, 0, 65535, tcp_callback);

вот тех 65535 ?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Aug 8 2014, 19:50
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



ничего не понял но как-то уже работает.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Aug 9 2014, 06:29
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



poll_socket - эта функция вызывается типа много раз, постоянно пока жив сокет.

сначала она идет по пути

Код
tcp_close (tcp_soc);
    
  state = tcp_get_state (tcp_soc);
  if (state > TCP_STATE_LISTEN)
        {
    /* Closing procedure is on-going */
    return;
        }


когда сокет перейдет в состояние LISTEN сработает

Код
if (state == TCP_STATE_LISTEN)
        {
    /* Socket has TCP_TYPE_SERVER attribute */
    /* needs additional close request.      */
    tcp_close (tcp_soc);
        }


а потом и сокет грохнется.

Другими словами если хотите закрыть сокет можно вызывать tcp_close пока сокет не перейдет в состояние закрыт, а потом его грохнуть. Просто между клозами надо вызывать еще функцию обработки стека.


Цитата
вот тех 65535

да это 65535 секунд, если в течении этого времени не поступит никаких данных, стек сокет без KEEP_ALIVE закроет, а сокет с KEEP_ALIVE пошлет специальный пакет проверки жизни сокета, и если на него ответят то все ок, а если нет то также закроет сокет. На пакет отвечают на уровне стека приемника, то есть винда сама отвечает на кип алайв пакеты.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th July 2025 - 23:34
Рейтинг@Mail.ru


Страница сгенерированна за 0.01443 секунд с 7
ELECTRONIX ©2004-2016