[Solved] Recipes for being a TCP server ...
Posted: Mon Sep 26, 2016 3:19 am
I am testing out logic on being a socket server. In my simple case, my goal was to start listening on an incoming socket port and merely log when a client connects. I created the following logic fragment using the sockets API which compiles cleanly.
My questions relate to the correct architecture and flow constraints. For example, in this simple story, the accept() call is a blocking call. My understanding is that the ESP32 now runs two cores ... one for the network/wifi/others and the other core for user applications. Does this mean that I can now block in my app code with impunity?
Given that control is passed to me in app_main() ... can I block in app_main() or should I spawn a task at the FreeRTOS level and then block in that task?
When I run my app, it "seems" to work to a point. I see the messages. From a client machine, I can even form a connection to port 80 on the ESP32 and see the message that we accepted a client connection. Unfortunately, we then abend and I'm not yet anywhere near convinced what I attempted was valid ... hence the questions.
... a few days later ...
I found that my abend at the end of the function was caused by not calling vTaskDelete() which appears to be mandatory before ending a task. This was not related to any sockets issues. Further testing seems to show the sockets APIs functioning great and allow local task blocking without breaking the overall architecture.
Code: Select all
static void initSockets() {
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("New sock = %d\n", sock);
struct sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(80);
int rc = bind(sock, (struct sockaddr *)&serverAddress, sizeof(serverAddress));
checkSocketRC(rc, "bind");
printf("bind completed!\n");
rc = listen(sock, 10);
checkSocketRC(rc, "listen");
printf("listen completed!\n");
struct sockaddr_in clientAddress;
socklen_t clientAddressLength = sizeof(clientAddress);
int clientSock = accept(sock, (struct sockaddr *)&clientAddress, &clientAddressLength);
checkSocketRC(clientSock, "accept");
printf("Accepted a client connection\n");
}
Given that control is passed to me in app_main() ... can I block in app_main() or should I spawn a task at the FreeRTOS level and then block in that task?
When I run my app, it "seems" to work to a point. I see the messages. From a client machine, I can even form a connection to port 80 on the ESP32 and see the message that we accepted a client connection. Unfortunately, we then abend and I'm not yet anywhere near convinced what I attempted was valid ... hence the questions.
... a few days later ...
I found that my abend at the end of the function was caused by not calling vTaskDelete() which appears to be mandatory before ending a task. This was not related to any sockets issues. Further testing seems to show the sockets APIs functioning great and allow local task blocking without breaking the overall architecture.