diff --git a/ssocket.h b/ssocket.h index 271520b..c4005be 100644 --- a/ssocket.h +++ b/ssocket.h @@ -4,6 +4,10 @@ #include #include +#define SSOCKET_VERSION_MAJOR 1 +#define SSOCKET_VERSION_MINOR 0 +#define SSOCKET_VERSION_PATCH 2 + #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) @@ -55,6 +59,7 @@ #if WIN_PART #include +#include #include #define strcasecmp _stricmp #define strncasecmp _strnicmp @@ -64,8 +69,8 @@ #include #include #include - #define SOCKET long long int +//#define INVALID_SOCKET (SOCKET)(~0) #endif #ifndef ZZY_SLEEP @@ -87,14 +92,26 @@ 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, + + ERR_SOCK_ADDRINFO, + //getaddrinfo + ERR_SOCK_EAI_MAPPING_NOT_EXIST, + ERR_SOCK_EAI_AGAIN, + ERR_SOCK_EAI_BADFLAGS, + ERR_SOCK_EAI_FAIL, + ERR_SOCK_EAI_FAMILY, + ERR_SOCK_EAI_MEMORY, + ERR_SOCK_EAI_NONAME, + ERR_SOCK_EAI_SERVICE, + ERR_SOCK_EAI_SOCKTYPE, }; static inline int make_sock(SOCKET* sock); @@ -110,73 +127,130 @@ static inline void sock_thread(void(*thread_func)(void*), void* data); #define _SOCKET_TEST_IP "127.0.0.1" #define _SOCKET_TEST_PORT 6789 +static inline int _socket(SOCKET* sock, const char* ip, const char* port); +static inline int _connect(SOCKET sock, const char* ip, const char* port); +static inline int _bind(SOCKET sock, const char* ip, const char* port); +static inline int _bindlisten(SOCKET sock, const char* ip, const char* port); -//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 _sock(SOCKET* sock, int af, int type); +static inline int make_sock(SOCKET* sock) { return make_sock_tcp4(sock); }; +static inline int make_sock_tcp4(SOCKET* sock) { return _sock(sock, AF_INET, SOCK_STREAM); } +static inline int make_sock_tcp6(SOCKET* sock) { return _sock(sock, AF_INET6, SOCK_STREAM); } +static inline int make_sock_udp4(SOCKET* sock) { return _sock(sock, AF_INET, SOCK_DGRAM); } +static inline int make_sock_udp6(SOCKET* sock) { return _sock(sock, AF_INET6, SOCK_DGRAM); } -static inline int make_sock(SOCKET* sock) { +static inline int _sock(SOCKET* sock, int af, int type) { #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) { + *sock = socket(af, type, 0); + if (*sock == INVALID_SOCKET) { 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); +static inline int _sock_eai_res_map(int res) { + switch (res) { + case EAI_AGAIN: return ERR_SOCK_EAI_AGAIN; + case EAI_BADFLAGS: return ERR_SOCK_EAI_BADFLAGS; + case EAI_FAIL: return ERR_SOCK_EAI_FAIL; + case EAI_FAMILY: return ERR_SOCK_EAI_FAMILY; + case EAI_MEMORY: return ERR_SOCK_EAI_MEMORY; + case EAI_NONAME: return ERR_SOCK_EAI_NONAME; + case EAI_SERVICE: return ERR_SOCK_EAI_SERVICE; + case EAI_SOCKTYPE: return ERR_SOCK_EAI_SOCKTYPE; + default: return ERR_SOCK_EAI_MAPPING_NOT_EXIST; } +} - if(connect(sock, (struct sockaddr*)&saddr, sizeof(saddr))) { - return ERR_SOCK_CONNECT; +static inline int _socket(SOCKET* sock, const char* ip, const char* port) { + struct addrinfo inf = { 0 }; + struct addrinfo* res_addr = NULL; + int res = getaddrinfo(ip, port, &inf, &res_addr); + if (res != 0) { + return _sock_eai_res_map(res); } - return ERR_SOCK_SUCCESS; + for (struct addrinfo* p = res_addr; p != NULL; p = p->ai_next) { + if (*sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) { + if (*sock == INVALID_SOCKET) { + return ERR_SOCK_CREATE_SOCKET; + } + freeaddrinfo(res_addr); + return ERR_SOCK_SUCCESS; + } + } + freeaddrinfo(res_addr); + return ERR_SOCK_CONNECT; +} + +static inline int _connect(SOCKET sock, const char* ip, const char* port) { + struct addrinfo inf = { 0 }; + struct addrinfo* res_addr = NULL; + int res = getaddrinfo(ip, port, &inf, &res_addr); + if (res != 0) { + return _sock_eai_res_map(res); + } + for (struct addrinfo* p = res_addr; p != NULL; p = p->ai_next) { + if (connect(sock, p->ai_addr, p->ai_addrlen) == 0) { + freeaddrinfo(res_addr); + return ERR_SOCK_SUCCESS; + } + } + freeaddrinfo(res_addr); + return ERR_SOCK_CONNECT; +} + +static inline int _bind(SOCKET sock, const char* ip, const char* port) { + struct addrinfo inf = { 0 }; + struct addrinfo* res_addr = NULL; + int res = getaddrinfo(ip, port, &inf, &res_addr); + if (res != 0) { + return ERR_SOCK_ADDRINFO; + } + for (struct addrinfo* p = res_addr; p != NULL; p = p->ai_next) { + if (bind(sock, p->ai_addr, p->ai_addrlen) == 0) { + freeaddrinfo(res_addr); + return ERR_SOCK_SUCCESS; + } + } + freeaddrinfo(res_addr); + return ERR_SOCK_CONNECT; +} + +static inline int _bindlisten(SOCKET sock, const char* ip, const char* port) { + int res = _bind(sock, ip, port); + if(res == ERR_SOCK_SUCCESS){ + if (listen(sock, SOMAXCONN) == 0) { + return ERR_SOCK_SUCCESS; + } + return ERR_SOCK_LISTEN; + } + return res; +} + +static inline int sock_connect(SOCKET sock, const char* connect_ip, unsigned short port) { + char buf[8] = { 0 }; + sprintf(buf, "%u", port); + return _connect(sock, connect_ip, buf); } 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; + char buf[8] = { 0 }; + sprintf(buf, "%u", port); + return _bindlisten(sock, server_ip, buf); } static inline int sock_accpet(SOCKET sock,SOCKET* client, char** accept_ip, unsigned short* port) { - struct sockaddr_in caddr; + struct sockaddr_in caddr = { 0 }; socklen_t addrLen = sizeof(struct sockaddr_in); if(client == NULL) { @@ -212,7 +286,7 @@ static inline int make_server_sock(SOCKET* sock, const char* server_ip, unsigned } res = sock_bindlisten(*sock, server_ip, port); - if(res != ERR_SOCK_SUCCESS) { + if(res != ERR_SOCK_SUCCESS) { return res; } @@ -267,6 +341,16 @@ static inline void get_sock_err(char* buff_128, size_t buff_len, int errcode) { // ERR_SOCK_CONNECT, // }; +//https://learn.microsoft.com/zh-cn/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo?redirectedfrom=MSDN +//错误值 WSA 等效项 说明 +//EAI_AGAIN WSATRY_AGAIN 名称解析暂时失败。 +//EAI_BADFLAGS WSAEINVAL 为 pHints 参数的 ai_flags 成员提供了无效值。 +//EAI_FAIL WSANO_RECOVERY 名称解析中发生不可恢复的失败。 +//EAI_FAMILY WSAEAFNOSUPPORT 不支持 pHints 参数的 ai_family 成员。 +//EAI_MEMORY WSA_NOT_ENOUGH_MEMORY 内存分配失败。 +//EAI_NONAME WSAHOST_NOT_FOUND 所提供的参数的名称未解析,或者未提供 pNodeName 和 pServiceName 参数。 +//EAI_SERVICE WSATYPE_NOT_FOUND pHints 参数的指定ai_socktype成员不支持 pServiceName 参数。 +//EAI_SOCKTYPE WSAESOCKTNOSUPPORT 不支持 pHints 参数的 ai_socktype 成员。 sprintf(buff_128, "%3d", errcode); } diff --git a/test/server/server.c b/test/server/server.c index 8911227..49cf8e7 100644 --- a/test/server/server.c +++ b/test/server/server.c @@ -1,6 +1,7 @@ #include #include #include "../../ssocket.h" +#include #define CLIENT_SIZE 32 SOCKET sfd; @@ -81,6 +82,7 @@ void acceptfunc(void* param) { int main() { + char Buf[128]; int res = make_server_sock(&sfd, _SOCKET_TEST_IP, _SOCKET_TEST_PORT); if(res != 0) {