Skip to content

Instantly share code, notes, and snippets.

@projectgus
Created January 9, 2018 23:21
Show Gist options
  • Save projectgus/9e620470817d1b99422ef2cad4a155ba to your computer and use it in GitHub Desktop.
Save projectgus/9e620470817d1b99422ef2cad4a155ba to your computer and use it in GitHub Desktop.
Basic TCP socket listen/accept/select demonstration
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
esp_err_t event_handler(void *ctx, system_event_t *event)
{
return ESP_OK;
}
void app_main(void)
{
nvs_flash_init();
tcpip_adapter_init();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
wifi_config_t sta_config = {
.sta = {
.ssid = "my_ssid",
.password = "my_password",
.bssid_set = false
}
};
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
ESP_ERROR_CHECK( esp_wifi_connect() );
/* This is almost all a quick adaptation of Wikipedia's example:
https://en.wikipedia.org/wiki/Berkeley_sockets#Server
*/
struct sockaddr_in sa;
int listen_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_sock == -1) {
perror("cannot create socket");
exit(EXIT_FAILURE);
}
memset(&sa, 0, sizeof sa);
const int PORT = 1100;
sa.sin_family = AF_INET;
sa.sin_port = htons(PORT);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listen_sock,(struct sockaddr *)&sa, sizeof sa) == -1) {
perror("bind failed");
close(listen_sock);
return;
}
if (listen(listen_sock, 10) == -1) {
perror("listen failed");
close(listen_sock);
return;
}
printf("Listening for connections on port %d\n", PORT);
for (;;) {
int conn_sock = accept(listen_sock, NULL, NULL);
if (conn_sock < 0) {
perror("accept failed");
close(listen_sock);
exit(EXIT_FAILURE);
}
printf("Connection received. Waiting for input...\n");
/* Wait for some input */
struct timeval timeout = {
.tv_sec = 10,
.tv_usec = 0,
};
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(conn_sock, &rfds);
/* Task will block until some data is available to read
from conn_sock... */
int r = select(conn_sock + 1, &rfds, NULL, NULL, &timeout);
if (r < 0) {
perror("select failed");
return;
}
else if (r == 0) {
printf("Timed out with no input received.\n");
}
else { // r > 0
uint8_t buf[128] = { 0 };
r = read(conn_sock, buf, sizeof(buf)-1);
printf("Received %d bytes: %s\n", r, buf);
}
const char *msg = "All done. Bye bye!\n";
write(conn_sock, msg, strlen(msg));
printf("Closing connection, waiting for another one...\n");
if (shutdown(conn_sock, SHUT_RDWR) == -1) {
perror("shutdown failed");
close(conn_sock);
close(listen_sock);
exit(EXIT_FAILURE);
}
close(conn_sock);
}
close(listen_sock);
printf("Done!\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment