Skip to content

Instantly share code, notes, and snippets.

@henkman
Last active November 16, 2023 19:54
Show Gist options
  • Save henkman/1ddbc8ad6c5efe23b6d791e5304afd5a to your computer and use it in GitHub Desktop.
Save henkman/1ddbc8ad6c5efe23b6d791e5304afd5a to your computer and use it in GitHub Desktop.
/**
// SAMPLE
int main(void) {
SocketInit();
struct sockaddr_in addr;
SocketResolve(&addr, "localhost", 5432);
Socket sock = SocketUDP(false);
// connected udp can use send/recv instead of sendto/recvfrom
connect(sock, (const struct sockaddr *) &addr, sizeof(addr));
const char *data = "hello world";
send(sock, data, strlen(data), 0);
struct timeval timeout = {0};
timeout.tv_sec = 4;
if(SocketReadable(sock, &timeout) > 0) {
uint8_t buf[8*1024];
int received = recv(sock, buf, 8*1024, 0);
if(received > 0) {
printf("%.*s\n", received, buf);
}
}
SocketClose(sock);
SocketQuit();
return 0;
}
*/
#include <netinet/in.h>
#ifdef _WIN32
#include <Ws2tcpip.h>
#include <winsock2.h>
typedef SOCKET Socket;
#else
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
typedef int Socket;
#endif
// returns 0 on success
static int SocketInit(void) {
#ifdef _WIN32
WSADATA wsa_data;
return WSAStartup(MAKEWORD(1, 1), &wsa_data);
#else
return 0;
#endif
}
// returns 0 on success
static int SocketQuit(void) {
#ifdef _WIN32
return WSACleanup();
#else
return 0;
#endif
}
// returns 0 on success
static int SocketResolve(struct sockaddr_in *addr, char *host, uint16_t port) {
struct hostent *h = gethostbyname(host);
if (h == NULL) {
return 1;
}
addr->sin_family = h->h_addrtype;
memcpy((char *)&(addr->sin_addr), h->h_addr, h->h_length);
addr->sin_port = htons(port);
return 0;
}
// SocketBind(sock, INADDR_ANY, port) to receive from everybody on port
// returns 0 on success
static int SocketBind(Socket sock, unsigned long address, uint16_t port) {
struct sockaddr_in server = {0};
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(address);
server.sin_port = htons(port);
return bind(sock, (struct sockaddr *)&server, sizeof(server));
}
// returns positive on success
static Socket SocketUDP(bool blocking) {
Socket s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (!blocking) {
fcntl(s, F_SETFL, O_NONBLOCK);
}
return s;
}
// returns positive on success
static Socket SocketTCP(bool blocking) {
Socket s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (!blocking) {
fcntl(s, F_SETFL, O_NONBLOCK);
}
return s;
}
// returns 0 on timeout, positive value on success
static int SocketReadable(Socket sock, struct timeval *timeout) {
fd_set socks;
FD_ZERO(&socks);
FD_SET(sock, &socks);
return select(sock + 1, &socks, NULL, NULL, timeout);
}
static void SocketClose(Socket sock) {
#ifdef _WIN32
closesocket(sock);
#else
close(sock);
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment