Skip to content

Instantly share code, notes, and snippets.

@viperscape
Last active March 5, 2018 01:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save viperscape/9f27692d87baad9655eac624d51efe90 to your computer and use it in GitHub Desktop.
Save viperscape/9f27692d87baad9655eac624d51efe90 to your computer and use it in GitHub Desktop.
cross os socket example
#include "socket.h"
// win32
// -lws2_32
int main() {
void* sock = socket_bind("127.0.0.1", 6063, 1);
socket_free(sock);
return 0;
}
#include "socket.h"
// win32
// -lws2_32
int main () {
void* sock = socket_bind("127.0.0.1", 6063, 0);
void* c_sock = socket_accept(sock);
socket_free(c_sock);
socket_free(sock);
return 0;
}
#include <stdio.h>
void* socket_bind (char* ip_addr, int port, int is_client);
void* socket_accept (void* sock_);
void socket_free(void* sock_);
struct sockaddr_in;
int socket_set (char* ip_addr, int port, struct sockaddr_in *sam);
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
int sock_num = 0;
int sock_init = 0;
WSADATA wsa;
int socket_init (SOCKET *sock) {
if (!sock_init) {
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) {
fprintf(stderr, "ERROR cannot load dll winsock: %d\n", WSAGetLastError());
return 0;
}
}
*sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (*sock == INVALID_SOCKET) {
fprintf(stderr, "ERROR cannot create socket: %d\n", WSAGetLastError());
return 0;
}
sock_num ++;
return 1;
}
void socket_free(void* sock_) {
SOCKET sock = (SOCKET) sock_;
closesocket(sock);
sock_num --;
if (sock_num < 1) {
WSACleanup();
sock_init = 0;
}
}
void* socket_bind (char* ip_addr, int port, int is_client) {
SOCKET sock = INVALID_SOCKET;
socket_init(&sock);
struct sockaddr_in sam;
socket_set(ip_addr, port, &sam);
int r;
if (!is_client) {
r = bind(sock, (struct sockaddr *) &sam, sizeof(sam));
if (r == SOCKET_ERROR) {
fprintf(stderr, "ERROR cannot bind: %d\n", WSAGetLastError());
return NULL;
}
listen(sock, SOMAXCONN);
}
else {
r = connect(sock, (struct sockaddr *) &sam, sizeof(sam));
if (r == SOCKET_ERROR) {
fprintf(stderr, "ERROR cannot connect: %d\n", WSAGetLastError());
return NULL;
}
}
return (void*) sock;
}
// blocking, accepts client sockets
void* socket_accept (void* sock_) {
SOCKET sock = (SOCKET) sock_;
struct sockaddr_in csam;
SOCKET c_sock = INVALID_SOCKET;
int c_sock_len = sizeof(struct sockaddr_in);
c_sock = accept(sock , (struct sockaddr *)&csam, &c_sock_len);
if (c_sock == INVALID_SOCKET) {
printf("accept failed with error code : %d" , WSAGetLastError());
return NULL;
}
sock_num++;
return (void*) c_sock;
}
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
void* socket_bind (char* ip_addr, int port, int is_client) {
int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
fprintf(stderr, "ERROR cannot create socket\n");
return NULL;
}
struct sockaddr_in sam;
socket_set(ip_addr, port, &sam);
int r;
if (!is_client) {
r = bind(sock, (struct sockaddr *) &sam, sizeof(sam));
if (r < 0) {
fprintf(stderr, "ERROR cannot bind\n");
return NULL;
}
listen(sock, SOMAXCONN);
}
else {
r = connect(sock, (struct sockaddr *) &sam, sizeof(sam));
if (r < 0) {
fprintf(stderr, "ERROR cannot connect\n");
return NULL;
}
}
void* sock_ = malloc(sizeof(int));
*((int*)sock_) = sock;
return sock_;
}
void* socket_accept (void* sock_) {
int* sock = (int*) sock_;
int c_sock;
unsigned int c_sock_len;
struct sockaddr_in csam;
c_sock_len = sizeof(csam);
c_sock = accept(*sock, (struct sockaddr *) &csam, &c_sock_len);
if (c_sock < 0) {
printf("Accept failed\n");
return NULL;
}
void* c_sock_ = malloc(sizeof(int));
*((int*)c_sock_) = c_sock;
return c_sock_;
}
void socket_free(void* sock_) {
if (sock_ == NULL) return;
int* sock = (int*)sock_;
close(*sock);
free(sock);
sock = NULL;
}
#endif
int socket_set (char* ip_addr, int port, struct sockaddr_in *sam) {
memset(sam, 0, sizeof(*sam));
sam->sin_family = AF_INET;
sam->sin_addr.s_addr = ip_addr ? inet_addr(ip_addr) : INADDR_ANY;
sam->sin_port = htons((u_short) port);
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment