LwIP - netconn API - отправить TCP-пакет, пока процесс заблокирован?

Я использую FreeRTOS + LwIP для разработки устройства вызова прикроватной медсестры на базе Ethernet. После прочтения некоторых примеров и документов я хочу использовать netconn API LwIP для отправки и получения данных по TCP, потому что я не знаком с API стиля BSD, и необработанный API может быть трудным.

Я знаю, что функция netconn_accept() будет блокировать процесс до тех пор, пока не поступит запрос на соединение с удаленного хоста, а функция netconn_recv() также заблокирует процесс, ожидая прибытия данных ... обе эти функции будут блокировать Этот процесс хорош для сервера, получающего данные, однако мое устройство также должно действовать как клиент, которому необходимо инициировать «звонок» в центр медсестер, когда пациент нажимает кнопку. Так как же он может инициировать отправку TCP-пакета, в то время как он также ожидает подключения (блокируя процесс) от удаленного хоста?

Мне нужно отправить TCP, потому что я должен использовать SIP (протокол инициации сеанса), чтобы инициировать вызов, он должен быть надежным, потому что это медицинское устройство. Большое тебе спасибо


@Kyle Heironimus, @werewindle Я добавляю вас к своему вопросу, потому что я знаю, что у вас есть опыт работы с LwIP, надеюсь, это не доставит вам неудобств, и надеюсь, что вы можете помочь, спасибо.


person eepty    schedule 22.04.2012    source источник
comment
Поскольку я использую FreeRTOS, сегодня я попытался использовать два потока, один как сервер, ожидающий подключения, другой как клиент, чтобы открыть TCP-соединение, когда это необходимо. Серверный поток работает хорошо, но на стороне клиента он всегда возвращает ошибку, когда я вызываю _1 _... Я пытался использовать один и тот же другой порт для сервера и клиента, но все равно не удалось   -  person eepty    schedule 23.04.2012
comment
пожалуйста, помогите мне с этой проблемой, stackoverflow.com/questions/51112786/   -  person Nitin Rawal    schedule 30.06.2018


Ответы (1)


Вы не можете отправлять данные на удаленный хост, пока он не инициировал соединение. В этом нет никакого смысла. Мой вопрос: вы хотите, чтобы ваше устройство подключалось к удаленному хосту, или вы хотите, чтобы удаленный хост инициировал соединение с вашим устройством?

Прямо сейчас вы используете netconn_accept на своем устройстве - это означает, что вы ждете, пока удаленный хост инициирует соединение с вашим устройством, прежде чем ваше устройство сможет передать сигнал удаленному хосту. Это вполне ожидаемое поведение для написанного вами кода, но, похоже, вас это беспокоит. Разве это не твое намерение? Если нет, то почему вы его так запрограммировали? Другой вариант - настроить ваше устройство на инициацию соединения с удаленным хостом. здесь есть пример такого использования netconns. Конечно, это также связано с изменениями в другом устройстве в вашей системе.

Итак, мораль этой истории заключается в том, что вы не можете отправлять данные, когда нет подключения, и вы ждете подключения, прежде чем отправлять данные. Вы не хотите ждать подключения, поэтому вам нужно изменить свое программное обеспечение, чтобы инициировать подключение, а не ждать, пока другая сторона инициирует его.

Другая проблема, с которой вы можете столкнуться, заключается в том, что вы хотите иметь возможность отправлять и получать данные по одному и тому же соединению одновременно. Большинство примеров, которые я видел для lwip, включают в себя блокировку вызовов, ожидающих данных, а затем реакцию на эти данные, отправляя что-то обратно. Иногда вы хотите передать что-то обратно, не получив сначала. Я тоже могу помочь с этим.

Это то, что у меня сработало, когда я создал прослушивающее соединение netconn.

Во-первых, вам нужно включить тайм-ауты, установив:

#define LWIP_SO_RCVTIMEO 1

Затем вам нужно настроить netconn примерно так:

pxTCPListener = netconn_new (NETCONN_TCP);

netconn_bind (pxTCPListener, NULL, 23);

netconn_listen (pxTCPListener);

pxNewConnection = netconn_accept (pxTCPListener); // Это блокируется до тех пор, пока соединение не будет принято

// Это важная строка!

pxNewConnection-> recv_timeout = 10; // обратите внимание: это миллисекунды - lwip работает в мс

// Это повторяется до тех пор, пока соединение не будет закрыто

while (! ERR_IS_FATAL (pxNewConnection-> err)) {// Фатальные ошибки включают закрытие, сброс, прерывание соединения и т. д.

// Этот вызов netconn_recv теперь будет ждать 10 мсек для любых новых данных, а затем вернется

if ((pxRxBuffer = netconn_recv (pxNewConnection))! = NULL) {

// Обрабатываем полученные данные

}

// Здесь делайте любые передачи, которые хотите

} // Конец цикла while сверху

Этот код позволит вам одновременно передавать и получать, не беспокоясь о блокировке.

person Stephen Friederichs    schedule 26.04.2012
comment
Спасибо, Стивен, устройство вызова медсестры будет работать как сервер, ожидая подключения, - person eepty; 26.04.2012
comment
Ага ... почему это? Похоже, что вызывающее устройство должно инициировать соединение с сервером, поскольку действие, которое запускает все это, заключается в том, что кто-то нажимает на нем кнопку, а не ждет, пока что-то подключится к нему, чтобы оно могло сказать, что была нажата кнопка. - person Stephen Friederichs; 26.04.2012
comment
Большое спасибо за подробный ответ Стивену. Устройство похоже на телефон, оно обычно ожидает соединения, действует как сервер, но если человек нажимает на нем кнопку, оно инициирует соединение, действует как клиент. Эти две ситуации не будут существовать одновременно, и обе ситуации связаны с приемом и передачей. Недавно мне удалось реализовать эти две задачи по отдельности ... после долгого чтения ... Я разделил их на две разные задачи во FreeRTOS, включение одной задачи будет блокировать другую. Я тестировал каждую задачу отдельно, но не тестировал их совместную работу ... Я новичок в RTOS, но попробую - person eepty; 26.04.2012
comment
Привет, Стивен, твоя реплика while(!ERR_IS_FATAL(pxNewConnection->err)) мне очень помогла. Хотя я могу получать и отправлять раньше, но мне нужно подключать и отключать TCP-соединение для каждого приема, в противном случае программа будет зависать. Еще раз спасибо - person eepty; 29.04.2012
comment
Да, для меня это тоже было хорошо. Не так много примеров полнодуплексной связи. - person Stephen Friederichs; 29.04.2012