#ifndef _SSOCKET_H_ #define _SSOCKET_H_ #include #include #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 #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 #include #define strcasecmp _stricmp #define strncasecmp _strnicmp #define socklen_t int #elif LINUX_PART #include #include #include #include #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