Socket and ClientInfo std::string Removal
The Socket class virtual methods getpeername() and getsockname() that returned std::string have been removed. The ClientInfo struct no longer contains std::string fields.
This is a breaking change for external components in ESPHome 2026.1.0 and later.
Background
Section titled “Background”PR #12566: Eliminate std::string from ClientInfo struct
This PR removes heap-allocated strings from socket and API connection code:
- Saves ~38 bytes of RAM per active API connection
- Reduces flash by 516 bytes on ESP32-IDF
- Eliminates heap fragmentation from connection handling
What’s Changing
Section titled “What’s Changing”Socket class methods removed
Section titled “Socket class methods removed”// Removed - heap-allocating virtual methodsvirtual std::string getpeername();virtual std::string getsockname();New buffer-based API
Section titled “New buffer-based API”// New - write to provided buffer// Returns bytes written (can be ignored for simple logging)size_t getpeername_to(std::span<char, SOCKADDR_STR_LEN> buf);size_t getsockname_to(std::span<char, SOCKADDR_STR_LEN> buf);
// Buffer size constant (compile-time, based on IPv6 support)socket::SOCKADDR_STR_LEN // 16 bytes (IPv4-only) or 46 bytes (IPv6-enabled)APIFrameHelper buffer changes
Section titled “APIFrameHelper buffer changes”// Before - heap-allocated strings in APIFrameHelperclass APIFrameHelper { std::string client_info_; // ...};
// After - fixed buffers in APIFrameHelperclass APIFrameHelper { char client_name_[CLIENT_INFO_NAME_MAX_LEN]; // 32 bytes for client name char client_peername_[socket::SOCKADDR_STR_LEN]; // 16/46 bytes for IP address // ...};APIConnection getters
Section titled “APIConnection getters”// Before - returned std::stringconst std::string &get_name() const;const std::string &get_peername() const;
// After - returns const char*const char *get_name() const;const char *get_peername() const;Who This Affects
Section titled “Who This Affects”External components that:
- Call
getpeername()orgetsockname()on socket objects - Access
APIFrameHelperclient name/peername fields - Call
get_name()orget_peername()onAPIConnection
Standard YAML configurations are not affected.
Migration Guide
Section titled “Migration Guide”1. Socket getpeername/getsockname
Section titled “1. Socket getpeername/getsockname”// Before - heap allocationstd::string peer = socket->getpeername();ESP_LOGD(TAG, "Connected from: %s", peer.c_str());
// After - stack bufferchar peer[socket::SOCKADDR_STR_LEN];socket->getpeername_to(peer);ESP_LOGD(TAG, "Connected from: %s", peer);2. Buffer size constant
Section titled “2. Buffer size constant”SOCKADDR_STR_LEN is a compile-time constant sized for your build configuration:
// Works for both IPv4 and IPv6 - size determined at compile timechar buffer[socket::SOCKADDR_STR_LEN];
// IPv4-only builds: 16 bytes (fits "255.255.255.255")// IPv6-enabled builds: 46 bytes (fits full IPv6 addresses)3. APIConnection name access
Section titled “3. APIConnection name access”// Beforeconst std::string &name = connection->get_name();const std::string &peer = connection->get_peername();
// After - returns const char*const char *name = connection->get_name();const char *peer = connection->get_peername();
// Direct logging (no .c_str() needed)ESP_LOGD(TAG, "Client: %s from %s", name, peer);4. Storing the address
Section titled “4. Storing the address”If you need to store the address, copy it to your own buffer:
// Stack buffer for temporary usechar peer[socket::SOCKADDR_STR_LEN];socket->getpeername_to(peer);
// If you need to store it (snprintf ensures null-termination)char stored_peer[socket::SOCKADDR_STR_LEN];snprintf(stored_peer, sizeof(stored_peer), "%s", peer);Supporting Multiple ESPHome Versions
Section titled “Supporting Multiple ESPHome Versions”#if ESPHOME_VERSION_CODE >= VERSION_CODE(2026, 1, 0) // New API - buffer-based char peer[socket::SOCKADDR_STR_LEN]; socket->getpeername_to(peer); ESP_LOGD(TAG, "Peer: %s", peer);#else // Old API - heap-allocating std::string peer = socket->getpeername(); ESP_LOGD(TAG, "Peer: %s", peer.c_str());#endifTimeline
Section titled “Timeline”- ESPHome 2026.1.0 (January 2026): Old methods removed, new buffer-based API required
- No deprecation period - methods removed directly
Finding Code That Needs Updates
Section titled “Finding Code That Needs Updates”# Find getpeername/getsockname callsgrep -rn "getpeername()" your_component/grep -rn "getsockname()" your_component/
# Find APIFrameHelper usagegrep -rn "APIFrameHelper" your_component/
# Find APIConnection name accessgrep -rn "get_name()" your_component/grep -rn "get_peername()" your_component/Questions?
Section titled “Questions?”If you have questions about migrating your external component, please ask in:
- ESPHome Discord - #devs channel
- ESPHome GitHub Discussions
Related Documentation
Section titled “Related Documentation”Copyright © 2026 ESPHome - A project from the Open Home Foundation
Comments
Feel free to leave a comment here to discuss this post with others. You can ask questions, share your experience, or suggest improvements. If you have a question about a specific feature or issue, please consider using the ESPHome Discord. Stick to English and follow ESPHome's code of conduct. These comments exist on a discussion on GitHub, so you can also comment there directly if you prefer.