Skip to content

Instantly share code, notes, and snippets.

@stakach
Created February 11, 2025 21:26
Show Gist options
  • Save stakach/4d68e19e14feeaf251686ae6aaa54b77 to your computer and use it in GitHub Desktop.
Save stakach/4d68e19e14feeaf251686ae6aaa54b77 to your computer and use it in GitHub Desktop.
non blocking socket check windows
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdio.h>
// Helper function to print Winsock error messages.
void print_wsa_error(const char *msg) {
int errCode = WSAGetLastError();
LPVOID errorText = NULL;
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&errorText,
0,
NULL
);
if (errorText != NULL) {
fprintf(stderr, "%s: %s\n", msg, (char *)errorText);
LocalFree(errorText);
} else {
fprintf(stderr, "%s: Unknown error %d\n", msg, errCode);
}
}
int check_socket_event(SOCKET sock) {
// Create an event.
WSAEVENT event = WSACreateEvent();
if (event == WSA_INVALID_EVENT) {
print_wsa_error("WSACreateEvent failed");
return -1;
}
// Associate the event with FD_READ, FD_WRITE, and FD_CLOSE notifications.
if (WSAEventSelect(sock, event, FD_READ | FD_WRITE | FD_CLOSE) == SOCKET_ERROR) {
print_wsa_error("WSAEventSelect failed");
WSACloseEvent(event);
return -1;
}
// Perform a non-blocking wait for the event (timeout 0 ms).
DWORD waitResult = WSAWaitForMultipleEvents(1, &event, FALSE, 0, FALSE);
if (waitResult == WSA_WAIT_FAILED) {
print_wsa_error("WSAWaitForMultipleEvents failed");
WSACloseEvent(event);
return -1;
} else if (waitResult == WSA_WAIT_TIMEOUT) {
printf("No event triggered.\n");
WSACloseEvent(event);
return 0;
}
// An event has been signaled; retrieve the event details.
WSANETWORKEVENTS networkEvents;
if (WSAEnumNetworkEvents(sock, event, &networkEvents) == SOCKET_ERROR) {
print_wsa_error("WSAEnumNetworkEvents failed");
WSACloseEvent(event);
return -1;
}
// Print status messages for each event.
if (networkEvents.lNetworkEvents & FD_READ) {
printf("Socket is readable.\n");
}
if (networkEvents.lNetworkEvents & FD_WRITE) {
printf("Socket is writable.\n");
}
if (networkEvents.lNetworkEvents & FD_CLOSE) {
printf("Socket is closed.\n");
}
int events = networkEvents.lNetworkEvents;
WSACloseEvent(event);
return events;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment