socket_compat — Cross-platform socket abstraction
1. Назначение
Унифицирует работу с UDP-сокетами между POSIX и Windows (MSYS2 UCRT64). Скрывает различия в типах дескрипторов (int vs SOCKET), инициализации подсистемы (WSAStartup/WSACleanup), кодах ошибок и сигнатурах системных вызовов.
2. Как пользоваться
Инициализация (однократно при старте)
На Windows WSAStartup/WSACleanup с refcount — можно вызывать init/cleanup вложенно.
Создание и настройка сокета
Отправка и приём
Обработка ошибок
Закрытие
Ключевые нюансы
- Всегда вызывать
socket_platform_init() перед работой — иначе на Windows сокеты не будут работать
- Всегда
socket_set_nonblocking() — u_async требует неблокирующих сокетов
socket_t — на POSIX int, на Windows SOCKET (unsigned)
SOCKET_INVALID — константа для невалидного сокета (-1 на POSIX, INVALID_SOCKET на Windows)
SOCKET_ERROR_CODE — код ошибки сокетных вызовов (-1 на POSIX, SOCKET_ERROR на Windows)
socket_strerror() на Windows использует статический буфер — не thread-safe для параллельного использования
socket_bind_to_device и socket_set_mark — только Linux, на остальных платформах возвращают -1 с DEBUG-сообщением
socket_close_wrapper на POSIX не закроет fd 0 (защита)
3. API
Типы и константы
| Имя |
Назначение |
socket_t |
Кроссплатформенный тип дескриптора сокета (int / SOCKET) |
SOCKET_INVALID |
Невалидный сокет (-1 / INVALID_SOCKET) |
SOCKET_ERROR_CODE |
Код ошибки сокетного вызова (-1 / SOCKET_ERROR) |
ERR_WOULDBLOCK / ERR_AGAIN / ERR_INTR |
Кроссплатформенные коды ошибок |
Инициализация
| Функция |
Назначение |
socket_platform_init() |
Инициализация сокетной подсистемы (WSAStartup на Windows). 0 — успех |
socket_platform_cleanup() |
Деинициализация (WSACleanup на Windows), refcount |
Создание и настройка
| Функция |
Назначение |
socket_create_udp(family) |
Создать UDP-сокет (AF_INET или AF_INET6) |
socket_set_nonblocking(sock) |
Перевести в неблокирующий режим |
socket_set_buffers(sock, snd, rcv) |
Установить SO_SNDBUF и SO_RCVBUF |
socket_set_reuseaddr(sock, reuse) |
Установить SO_REUSEADDR |
socket_bind_to_device(sock, ifname) |
Привязать к интерфейсу (Linux SO_BINDTODEVICE) |
socket_set_mark(sock, mark) |
Установить SO_MARK (Linux) |
I/O
| Функция |
Назначение |
socket_sendto(sock, buf, len, dest, dest_len) |
Отправить UDP-датаграмму |
socket_recvfrom(sock, buf, len, src, src_len) |
Принять UDP-датаграмму |
Утилиты
| Функция |
Назначение |
socket_get_error() |
Текущий код ошибки (inline: WSAGetLastError() / errno) |
socket_strerror(err) |
Текстовое описание ошибки (Windows: статический буфер, не thread-safe) |
socket_close_wrapper(sock) |
Закрыть сокет (POSIX: защита от закрытия fd 0) |
ss_get_port(addr) |
Извлечь порт в host byte order из sockaddr_storage |