clib/ssocket.h

288 lines
6.5 KiB
C

#ifndef _SSOCKET_H_
#define _SSOCKET_H_
#include <stdio.h>
#include <string.h>
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
#define _OS_WIN 1
//define something for Windows (32-bit and 64-bit, this part is common)
#ifdef _WIN64
#define _OS_WIN64 1
//define something for Windows (64-bit only)
#else
#define _OS_WIN32 1
//define something for Windows (32-bit only)
#endif
#elif __APPLE__
#define _OS_APPLE 1
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR
#define _OS_APPLE_SIM 1
// iOS, tvOS, or watchOS Simulator
#elif TARGET_OS_MACCATALYST
#define _OS_APPLE_CATA 1
// Mac's Catalyst (ports iOS API into Mac, like UIKit).
#elif TARGET_OS_IPHONE
#define _OS_APPLE_PHO 1
// iOS, tvOS, or watchOS device
#elif TARGET_OS_MAC
#define _OS_APPLE_MAC 1
// Other kinds of Apple platforms
#else
# error "Unknown Apple platform"
#endif
#elif __linux__
#define _OS_LINUX 1
// linux
#elif __unix__ // all unices not caught above
#define _OS_UNIX 1
// Unix
#elif defined(_POSIX_VERSION)
#define _OS_POSIX 1
// POSIX
#else
# error "Unknown compiler"
#endif
#if _OS_WIN
#define WIN_PART 1
#elif _OS_LINUX
#define LINUX_PART 1
#else
#error "Not Supported Operator System"
#endif
#if WIN_PART
#include <winsock2.h>
#include <windows.h>
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define socklen_t int
#elif LINUX_PART
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <strings.h>
#define SOCKET long long int
#endif
#ifndef ZZY_SLEEP
#define ZZY_SLEEP
#if WIN_PART
#define sleeps(s) Sleep(s*1000)
#define sleepms(ms) Sleep(ms)
#elif LINUX_PART
#define sleeps(s) sleep(s)
#define sleepms(ms) usleep(ms*1000)
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
enum {
ERR_SOCK_SUCCESS,
ERR_SOCK_MALLOC,
ERR_SOCK_NULLPTR,
ERR_SOCK_WSAStartup,
ERR_SOCK_DETERMINE_AGREEMENT,
ERR_SOCK_CREATE_SOCKET,
ERR_SOCK_BIND,
ERR_SOCK_LISTEN,
ERR_SOCK_ACCEPT,
ERR_SOCK_CONNECT,
};
static inline int make_sock(SOCKET* sock);
static inline int sock_connect(SOCKET sock, const char* connect_ip, unsigned short port);
static inline int sock_bindlisten(SOCKET sock, const char* server_ip, unsigned short port);
static inline int sock_accpet(SOCKET sock,SOCKET* client, char** accept_ip, unsigned short* port);
static inline int make_server_sock(SOCKET* sock, const char* server_ip, unsigned short port);
static inline int make_client_sock(SOCKET* sock, const char* connect_ip, unsigned short port);
static inline void close_sock(SOCKET sock);
static inline void out_sock_err(FILE* output, int errcode);
static inline void get_sock_err(char* buff_128, size_t buff_len, int errcode);
static inline void sock_thread(void(*thread_func)(void*), void* data);
#define _SOCKET_TEST_IP "127.0.0.1"
#define _SOCKET_TEST_PORT 6789
//SOCK_STREAM
//SOCK_DGRAM
//static inline int make_sock_tcp(SOCKET* sock) { return _make_sock(sock, AF_INET, SOCK_STREAM); }
//static inline int make_sock_udp(SOCKET* sock) { return _make_sock(sock, AF_INET, SOCK_DGRAM); }
static inline int make_sock(SOCKET* sock) {
#ifdef WIN_PART
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
return ERR_SOCK_WSAStartup;
}
if (HIBYTE(wsaData.wVersion) != 2 || \
LOBYTE(wsaData.wVersion) != 2) {
return ERR_SOCK_DETERMINE_AGREEMENT;
}
#endif
*sock = socket(AF_INET, SOCK_STREAM, 0);
if (*sock == -1) {
return ERR_SOCK_CREATE_SOCKET;
}
return ERR_SOCK_SUCCESS;
}
static inline int sock_connect(SOCKET sock, const char* connect_ip, unsigned short port) {
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
if(connect_ip == NULL) {
saddr.sin_addr.s_addr = INADDR_ANY;
}
else {
saddr.sin_addr.s_addr = inet_addr(connect_ip);
}
if(connect(sock, (struct sockaddr*)&saddr, sizeof(saddr))) {
return ERR_SOCK_CONNECT;
}
return ERR_SOCK_SUCCESS;
}
static inline int sock_bindlisten(SOCKET sock, const char* server_ip, unsigned short port) {
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
if(server_ip == NULL) {
saddr.sin_addr.s_addr = INADDR_ANY;
}
else {
saddr.sin_addr.s_addr = inet_addr(server_ip);
}
int res = bind(sock, (struct sockaddr*)&saddr, sizeof(saddr));
if (res == -1) {
return ERR_SOCK_BIND;
}
res = listen(sock, SOMAXCONN);
if (res == -1) {
return ERR_SOCK_LISTEN;
}
return ERR_SOCK_SUCCESS;
}
static inline int sock_accpet(SOCKET sock,SOCKET* client, char** accept_ip, unsigned short* port) {
struct sockaddr_in caddr;
socklen_t addrLen = sizeof(struct sockaddr_in);
if(client == NULL) {
return ERR_SOCK_NULLPTR;
}
*client = accept(sock,(struct sockaddr*) &caddr, &addrLen);
if (*client == -1) {
return ERR_SOCK_ACCEPT;
}
char* ip = (char*)malloc(32);
if(ip == NULL) {
return ERR_SOCK_MALLOC;
}
int buffLen = strlen( inet_ntoa(caddr.sin_addr) );
if(accept_ip != NULL) {
strncpy(ip, inet_ntoa(caddr.sin_addr), buffLen);
ip[buffLen] = '\0';
*accept_ip = ip;
}
if(port != NULL) {
*port = ntohs(caddr.sin_port);
}
return ERR_SOCK_SUCCESS;
}
static inline int make_server_sock(SOCKET* sock, const char* server_ip, unsigned short port) {
int res = make_sock(sock);
if(res != ERR_SOCK_SUCCESS) {
return res;
}
res = sock_bindlisten(*sock, server_ip, port);
if(res != ERR_SOCK_SUCCESS) {
return res;
}
return ERR_SOCK_SUCCESS;
}
static inline int make_client_sock(SOCKET* sock, const char* connect_ip, unsigned short port) {
int res = make_sock(sock);
if(res != ERR_SOCK_SUCCESS) {
return res;
}
if(connect_ip) {
res = sock_connect(*sock, connect_ip, port);
if(res != ERR_SOCK_SUCCESS) {
return res;
}
}
return ERR_SOCK_SUCCESS;
}
static inline void close_sock(SOCKET sock) {
if(sock == -1) {
return;
}
#if WIN_PART
closesocket(sock);
#elif LINUX_PART
close(sock);
#endif
}
static inline void out_sock_err(FILE* output, int errcode) {
fprintf(output, "%d", errcode);
}
static inline void get_sock_err(char* buff_128, size_t buff_len, int errcode) {
if(buff_len < 128) {
return;
}
// enum {
// ERR_SOCK_SUCCESS,
// ERR_SOCK_MALLOC,
// ERR_SOCK_NULLPTR,
// ERR_SOCK_WSAStartup,
// ERR_SOCK_DETERMINE_AGREEMENT,
// ERR_SOCK_CREATE_SOCKET,
// ERR_SOCK_BIND,
// ERR_SOCK_LISTEN,
// ERR_SOCK_ACCEPT,
// ERR_SOCK_CONNECT,
// };
sprintf(buff_128, "%3d", errcode);
}
static inline void sock_thread(void(*thread_func)(void*), void* data) {
#if WIN_PART
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL);
#elif LINUX_PART
pthread_t pid;
pthread_create(&pid, 0, (void*(*)(void*))thread_func, data);
#endif
}
#ifdef __cplusplus
}
#endif
#endif