Dear Contributors
Environment
- libcoap version : [v4.3.1-91-g78304f4]
- Build System: [CMake]
- Operating System: [Windows]
- Hosted Environment: [None]
Problem Description
As the title states,when I first run client.exe, an exception 0xC0000005 is thrown.
Expected Behavior
I expect that when running the client first, the client will wait until the server starts if the server does not start. Also, how can the client implement the ability to keep waiting for the server to come back online when it is not started or when it quits unexpectedly? I looked at the code in coap-client.c in the sample include libcoap and didn't find it. Maybe it's because I'm not good enough...
Also, I've been worried that pduh will cause a memory leak. If the client can't tell that the server is down, and then the client keeps generating pdu through the coap_new_pduh function, this results in a lot of pdu not being freed. Is there any other meansl to release it? Is there a function I should use to determine this and then release it manually? Please advise!
Actual Behavior
The client runs for a few seconds before the exception is thrown.
Steps to reproduce
- Run client.exe first.
- Wait a few seconds.
- The exception is then thrown
Code to reproduce this issue
I only changed this line of code.
diff --git a/client.cc b/client.cc
index a37d80f..946356a 100644
--- a/client.cc
+++ b/client.cc
@@ -25,7 +25,7 @@ main(void) {
coap_set_log_level(LOG_WARNING);
/* resolve destination address where server should be sent */
- if (resolve_address("coap.me", "5683", &dst) < 0) {
+ if (resolve_address("localhost", "5683", &dst) < 0) {
coap_log(LOG_CRIT, "failed to resolve address\n");
goto finish;
}
Debug Logs
I located the code that gave the error to the coap_io_process function,Under Debug, the call stack information is:
client.exe!_coap_socket_send�() (Unknown source:0)
client.exe!_coap_netif_dgrm_write�() (Unknown source:0)
client.exe!_coap_send_message_type�() (Unknown source:0)
kernel32.dll!77ccf989() (Unknown source:0)
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] (Unknown source:0)
ntdll.dll!77e174b4() (Unknown source:0)
ntdll.dll!77e17484() (Unknown source:0)
client.exe!_coap_session_connected�() (Unknown source:0)
v:1 t:CON c:GET i:fce5 {} [ Uri-Path:hello ]
Apr 27 16:04:24.056 WARN ** [::1]:52327 <-> [::1]:5683 UDP : coap_socket_recv: ICMP: 远程主机强迫关闭了一个现有的连接。
Exception thrown at 0x00367F3F in client.exe: 0xC0000005: Access violation reading location 0x00000014.
Other items if possible
When I run the server first, then the client, everything works fine.
I tried the following modifications, but nothing worked:
diff --git a/client.cc b/client.cc
index a37d80f..823abb2 100644
--- a/client.cc
+++ b/client.cc
@@ -6,18 +6,43 @@
#include <cstring>
#include <cstdlib>
#include <cstdio>
+#include <iostream>
+#include <thread>
+#include <atomic>
+#include <ctime>
+#include <iomanip>
#include "common.hh"
static int have_response = 0;
+constexpr int MAX_RETRIES = 1;
+int retries = 0;
+coap_pdu_t *pdu = nullptr;
+
+static int event_handler(coap_session_t *session, coap_event_t event) {
+ if (event == COAP_EVENT_MSG_RETRANSMITTED) {
+ retries++;
+ if (retries >= MAX_RETRIES) {
+ std::cout << "Reached max retries, waiting for server to start..." << std::endl;
+ coap_session_set_max_retransmit(session, -1); // Disable further retransmissions
+ std::this_thread::sleep_for(std::chrono::seconds(5)); // Wait for 5 seconds
+ retries = 0; // Reset the retries counter
+ coap_session_set_max_retransmit(session, COAP_DEFAULT_MAX_RETRANSMIT); // Enable retransmissions
+ coap_send(session, pdu); // Resend the PDU
+ }
+ }
+ std::cout << "Event: " << event << std::endl;
+ return 0;
+}
int
main(void) {
coap_context_t *ctx = nullptr;
- coap_session_t *session = nullptr;
coap_address_t dst;
+ coap_session_t *session = nullptr;
coap_pdu_t *pdu = nullptr;
- int result = EXIT_FAILURE;;
+ int result = EXIT_FAILURE;;
+ std::string textUrl = "hello";
coap_startup();
@@ -25,7 +50,7 @@ main(void) {
coap_set_log_level(LOG_WARNING);
/* resolve destination address where server should be sent */
- if (resolve_address("coap.me", "5683", &dst) < 0) {
+ if (resolve_address("localhost", "5683", &dst) < 0) {
coap_log(LOG_CRIT, "failed to resolve address\n");
goto finish;
}
@@ -44,15 +69,6 @@ main(void) {
coap_log(LOG_EMERG, "cannot create client session\n");
goto finish;
}
-
- /* coap_register_response_handler(ctx, response_handler); */
- coap_register_response_handler(ctx, [](auto, auto,
- const coap_pdu_t *received,
- auto) {
- have_response = 1;
- coap_show_pdu(LOG_WARNING, received);
- return COAP_RESPONSE_OK;
- });
/* construct CoAP message */
pdu = coap_pdu_init(COAP_MESSAGE_CON,
COAP_REQUEST_CODE_GET,
@@ -63,16 +79,52 @@ main(void) {
goto finish;
}
+ /* coap_register_response_handler(ctx, response_handler); */
+ coap_register_response_handler(ctx, [](auto, auto,
+ const coap_pdu_t *received,
+ auto) {
+ have_response = 1;
+ coap_show_pdu(LOG_WARNING, received);
+ return COAP_RESPONSE_OK;
+ });
+ coap_register_event_handler(ctx, event_handler);
+ coap_register_nack_handler(ctx, [](coap_session_t *session, const coap_pdu_t *sent,
+ const coap_nack_reason_t reason, const coap_mid_t mid) {
+ std::cout << "NACK received:"<< mid << std::endl;
+ });
+
+
/* add a Uri-Path option */
- coap_add_option(pdu, COAP_OPTION_URI_PATH, 5,
- reinterpret_cast<const uint8_t *>("hello"));
+ coap_add_option(pdu, COAP_OPTION_URI_PATH, 6,
+ reinterpret_cast<const uint8_t *>("helloo"));
coap_show_pdu(LOG_WARNING, pdu);
/* and send the PDU */
coap_send(session, pdu);
- while (have_response == 0)
- coap_io_process(ctx, COAP_IO_WAIT);
+ int attempts = 0;
+ int timestamp = 0;
+ while (attempts < 5)
+ {
+ coap_io_process(ctx, 1000);
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ auto time = std::time(nullptr);
+ std::cout << "["<< std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S") << "] " << std::endl;
+ if(result < 0)
+ attempts++;
+ }
result = EXIT_SUCCESS;
finish: