Compare commits

...

10 Commits

Author SHA1 Message Date
zzy
875f7e41d8 updata cmake 2023-11-04 14:10:32 +08:00
zzy
18d3be81bb dev 23.11.4 13:54 2023-11-04 13:54:38 +08:00
zzy
71820652af dev 1.0.5 release 2023-11-04 13:46:10 +08:00
4f8a389ce3 dev 1.0.5 linux 2023-11-04 13:39:50 +08:00
zzy
4c33b6442e dev add CmakeLists 2023-11-04 13:01:29 +08:00
zzy
fb1ff82d96 dev 1.0.5windows 2023-11-04 12:57:01 +08:00
zzy
a12cee77f1 dev bugfix socket close 2023-11-03 13:05:57 +08:00
zzy
ec69cfa8b2 hotfix 2023-11-02 23:30:19 +08:00
zzy
32a4a51964 dev send msg part 2023-11-02 23:21:03 +08:00
zzy
98794eb508 dev proj 2023-11-02 22:53:52 +08:00
19 changed files with 622 additions and 393 deletions

3
.gitignore vendored
View File

@ -1,8 +1,9 @@
*
!.gitignore
!doc.md
!README.txt
!version.txt
!doc.md
!CMakeLists.txt
!*/
!include/*
!doc/*

18
CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.22.1)
project(zzylib)
set(EXECUTABLE_OUTPUT_PATH ../)
set(C_STANDARD 99)
set(C_STANDARD_REQUIRED TRUE)
set(C_EXTENSIONS FALSE)
file(GLOB SRC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c)
add_library(${PROJECT_NAME} STATIC ${SRC_FILE})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
if(WIN32)
target_link_libraries(${PROJECT_NAME} wsock32 ws2_32)
endif()
# cmake ..
# cmake --build .

View File

@ -1,19 +1,14 @@
#ifndef _IINI_H_
#define _IINI_H_
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "sysenv.h"
#include <stddef.h>
#include <sysenv.h>
#if _OS_WIN
#ifndef strcasecmp
#define strcasecmp _stricmp
#endif
#ifndef strncasecmp
#define strncasecmp _strnicmp
#endif
#elif _OS_LINUX
#include <strings.h>
#else
#error "Not Supported Operator System"
#endif
@ -22,154 +17,13 @@
#define INICHAR char
#endif
#if !defined INI_BUFFER_SIZE
#define INI_BUFFER_SIZE 512
#endif
#ifdef __cplusplus
extern "C" {
#endif
static int ini_get_str(const INICHAR* filename, const INICHAR* section, const INICHAR* key,
int ini_get_str(const INICHAR* filename, const INICHAR* section, const INICHAR* key,
const INICHAR* def_vaule, INICHAR* buf, size_t szbuf);
static inline INICHAR* _ini_skip_leading(const INICHAR* str)
{
assert(str != NULL);
while ('\0' < *str && *str <= ' ')
str++;
return (INICHAR*)str;
}
static inline INICHAR* _ini_skip_trailing(const INICHAR* str, const INICHAR* base)
{
assert(str != NULL);
assert(base != NULL);
while (str > base && '\0' < *(str - 1) && *(str - 1) <= ' ')
str--;
return (INICHAR*)str;
}
static INICHAR* _ini_str_skip_trailing(INICHAR* str)
{
INICHAR* ptr = _ini_skip_trailing(strchr(str, '\0'), str);
assert(ptr != NULL);
*ptr = '\0';
return str;
}
static void _ini_clean_string(INICHAR** start_pptr, INICHAR** end_pptr) {
/* Remove a trailing comment */
int is_string = 0;
*start_pptr = _ini_skip_leading(*end_pptr + 1);
for (*end_pptr = *start_pptr; **end_pptr != '#' && **end_pptr != ';' && **end_pptr != '\0'; *end_pptr += 1) {
if (**end_pptr == '"') {
if (*(*end_pptr + 1) == '"') {
*end_pptr += 1; /* skip "" (both quotes) */
}
else {
is_string = !is_string;/* single quote, toggle isstring */
}
}
else if (*(*end_pptr) == '\\' && *(*end_pptr + 1) == '"') {
*end_pptr += 1; /* skip \" (both quotes */
}
}
**end_pptr = ' ';
*end_pptr = _ini_skip_trailing(*end_pptr, *start_pptr);
**end_pptr = '\0';
/* Remove double quotes surrounding a value */
if (**start_pptr == '"' && *(*end_pptr - 1) == '"') {
*end_pptr -= 1;
*start_pptr += 1;
**end_pptr = '\0';
}
}
static inline int _ini_str_get_section(INICHAR **start_pptr, INICHAR **end_pptr,
INICHAR* buf, size_t szbuf) {
*start_pptr = _ini_skip_leading(buf);
*end_pptr = strchr(buf, ']');
if (**start_pptr != '[' || *end_pptr == NULL) {
return -1;
}
/* When arrived here, a section was found; now optionally skip leading and
* trailing whitespace.
*/
assert(*start_pptr != NULL && **start_pptr == '[');
*start_pptr = _ini_skip_leading(*start_pptr + 1);
assert(*end_pptr != NULL && **end_pptr == ']');
*end_pptr = _ini_skip_trailing(*end_pptr, *start_pptr);
return 0;
}
static inline int _ini_str_get_key(INICHAR** start_pptr, INICHAR** end_pptr,
INICHAR* buf, size_t szbuf) {
*start_pptr = _ini_skip_leading(buf);
if (**start_pptr == '[' || **start_pptr == '#' || **start_pptr == ':') return -1;
*end_pptr = strchr(*start_pptr, '='); /* Parse out the equal sign */
if (*end_pptr == NULL) *end_pptr = strchr(*start_pptr, ':');
if (*end_pptr == NULL) return -1;
return 0;
}
static int _int_get_all_string(FILE* fp, const INICHAR* section, const INICHAR* key,
int idx_section, int idx_key, INICHAR* buf, size_t szbuf) {
int len = 0, idx = 0;
INICHAR* start_ptr, * end_ptr;
INICHAR local_buf[INI_BUFFER_SIZE] = { 0 };
assert(fp != NULL);
len = (section != NULL) ? (int)strlen(section) : 0;
/* Move through file 1 line at a time until a section is matched or EOF. If
* parameter Section is NULL, only look at keys above the first section. If
* idxSection is positive, copy the relevant section name.
*/
if (len > 0 || idx_section >= 0) {
assert(idx_section >= 0 || section != NULL);
idx = -1;
do {
if (fgets(local_buf, INI_BUFFER_SIZE, fp) == NULL) return -1;
if (_ini_str_get_section(&start_ptr, &end_ptr, local_buf, INI_BUFFER_SIZE) != 0) continue;
} while (!((int)(end_ptr - start_ptr) == len && section != NULL && strncasecmp(start_ptr, section, len) == 0));
}
/* Now that the section has been found, find the entry.
* Stop searching upon leaving the section's area.
*/
assert(key != NULL || idx_key >= 0);
len = (key != NULL) ? (int)strlen(key) : 0;
idx = -1;
do {
if (fgets(local_buf, INI_BUFFER_SIZE, fp) == NULL) return -1;
if (_ini_str_get_key(&start_ptr, &end_ptr, local_buf, INI_BUFFER_SIZE) != 0) continue;
} while (len != 0 && strncasecmp(start_ptr, key, len) != 0);
_ini_clean_string(&start_ptr, &end_ptr);
/* Copy up to BufferSize chars to buffer */
strncpy(buf, start_ptr, szbuf);
return 0;
}
static int ini_get_str(const INICHAR* filename, const INICHAR* section, const INICHAR* key,
const INICHAR* def_vaule, INICHAR* buf, size_t szbuf) {
FILE* fp = NULL;
int res = -1;
if (fp = fopen(filename, "rb")) {
res = _int_get_all_string(fp, section, key, -1, -1, buf, szbuf);
fclose(fp);
}
if (res != 0) {
strncpy(buf, ((def_vaule == NULL) ? (const char*)"" : def_vaule), szbuf);
buf[szbuf] = '\0';
}
res = strlen(buf);
return res;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,13 +1,19 @@
#ifndef _LLOG_H_
#define _LLOG_H_
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdbool.h>
#include <time.h>
#include <sysenv.h>
#if _OS_WIN
#elif _OS_LINUX
#else
#error "Not Supported Operator System"
#endif
typedef uint16_t log_mask_t;
#define LOG_MASK_ENDLINE (1 << 0)
@ -46,25 +52,6 @@ extern "C" {
enum { _LOG_TRACE, _LOG_DEBUG, _LOG_INFO, _LOG_WARN, _LOG_ERROR, _LOG_FATAL };
static const char* _log_level_strings[] = {
"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
};
#define LOG_COLOR(code) \033[##code##m
#define LOG_COLOR_TRACE LOG_COLOR(94)
#define LOG_COLOR_DEBUG LOG_COLOR(36)
#define LOG_COLOR_INFO LOG_COLOR(32)
#define LOG_COLOR_WARN LOG_COLOR(33)
#define LOG_COLOR_ERROR LOG_COLOR(31)
#define LOG_COLOR_FATAL LOG_COLOR(35)
#define _TO_STR(str) #str
#define TO_STR(str) _TO_STR(str)
static const char* _log_level_colors[] = {
TO_STR(LOG_COLOR_TRACE), TO_STR(LOG_COLOR_DEBUG), TO_STR(LOG_COLOR_INFO),
TO_STR(LOG_COLOR_WARN), TO_STR(LOG_COLOR_ERROR), TO_STR(LOG_COLOR_FATAL)
};
#define log_head_trace( log, szlog) log_fill_head_str(_LOG_TRACE, log, szlog, LOG_MASK_BASE_DEFAULT, __FILE__, __func__, __func__, __LINE__)
#define log_head_debug( log, szlog) log_fill_head_str(_LOG_DEBUG, log, szlog, LOG_MASK_BASE_DEFAULT, __FILE__, __func__, __func__, __LINE__)
#define log_head_info( log, szlog) log_fill_head_str(_LOG_INFO, log, szlog, LOG_MASK_BASE_DEFAULT, __FILE__, __func__, __func__, __LINE__)
@ -81,156 +68,34 @@ static const char* _log_level_colors[] = {
#define log_head_fatal_ex( log, szlog, mode, mask) log_fill_head_str(_LOG_FATAL, log, szlog, mask, __FILE__, mode, __func__, __LINE__)
#define log_head_ex(level, log, szlog, mode, mask) log_fill_head_str(level , log, szlog, mask, __FILE__, mode, __func__, __LINE__)
#define _LOG_MAX_HEAD_BUF_SIZE 256
struct _fill_head_parm {
int level;
char* buf;
size_t szbuf;
log_mask_t mask;
const char* file;
const char* mode;
const char* func;
int line;
struct tm* time;
};
static size_t _log_fill_head_time_ymd(struct _fill_head_parm* parm) {
log_mask_t mask = parm->mask;
char* buf = parm->buf;
size_t szbuf = parm->szbuf;
struct tm* time = parm->time;
if (LOG_MASK_TIME_YMD & mask) {
if (LOG_MASK_YEAR & mask) {
szbuf += strftime(buf + szbuf, _LOG_MAX_HEAD_BUF_SIZE - szbuf, "%Y", time);
}
else {
szbuf += sprintf(buf + szbuf, "Y");
}
if (LOG_MASK_MONTH & mask) {
szbuf += strftime(buf + szbuf, _LOG_MAX_HEAD_BUF_SIZE - szbuf, "-%m", time);
}
else {
szbuf += sprintf(buf + szbuf, "-M");
}
if (LOG_MASK_DAY & mask) {
szbuf += strftime(buf + szbuf, _LOG_MAX_HEAD_BUF_SIZE - szbuf, "-%d", time);
}
else {
szbuf += sprintf(buf + szbuf, "-D");
}
}
return szbuf;
}
static size_t _log_fill_head_time_hms(struct _fill_head_parm* parm) {
log_mask_t mask = parm->mask;
char* buf = parm->buf;
size_t szbuf = parm->szbuf;
struct tm* time = parm->time;
if (LOG_MASK_TIME_HMS & mask) {
if (LOG_MASK_HOUR & mask) {
szbuf += strftime(buf + szbuf, _LOG_MAX_HEAD_BUF_SIZE - szbuf, "%H", time);
}
else {
szbuf += sprintf(buf + szbuf, "h");
}
if (LOG_MASK_MINUTE & mask) {
szbuf += strftime(buf + szbuf, _LOG_MAX_HEAD_BUF_SIZE - szbuf, ":%M", time);
}
else {
szbuf += sprintf(buf + szbuf, ":m");
}
if (LOG_MASK_SECOND & mask) {
szbuf += strftime(buf + szbuf, _LOG_MAX_HEAD_BUF_SIZE - szbuf, ":%S", time);
}
else {
szbuf += sprintf(buf + szbuf, ":s");
}
}
return szbuf;
}
static size_t _log_fill_head_detail(struct _fill_head_parm* parm) {
log_mask_t mask = parm->mask;
char* buf = parm->buf;
size_t szbuf = parm->szbuf;
int file_offset = 0;
if (LOG_MASK_COLORS & mask) {
szbuf += sprintf(buf + szbuf, "%s%-5s\033[0m \033[90m",
_log_level_colors[parm->level],
(LOG_MASK_LEVEL & mask) ? _log_level_strings[parm->level] : "nan");
}
else {
szbuf += sprintf(buf + szbuf, "%-5s ",
(LOG_MASK_LEVEL & mask) ? _log_level_strings[parm->level] : "nan");
}
if (LOG_FILE_SIMPLE & mask) {
for (file_offset = strlen(parm->file);
file_offset > -1; file_offset -= 1) {
if (parm->file[file_offset] == '/' || parm->file[file_offset] == '\\') {
file_offset += 1;
break;
}
}
}
szbuf += sprintf(buf + szbuf, "%.128s:%.32s:%.32s:%d:",
(LOG_MASK_FILE & mask) ? parm->file + file_offset : "file",
(LOG_MASK_MODE & mask) ? parm->mode : "mode",
(LOG_MASK_FUNC & mask) ? parm->func : "func",
(LOG_MASK_LINE & mask) ? parm->line : 0);
if (LOG_MASK_COLORS & mask) {
szbuf += sprintf(buf + szbuf, "\033[0m");
}
return szbuf;
}
static inline size_t log_fill_head_str(int level, char* log, size_t szlog,
log_mask_t mask, const char* file, const char* mode, const char* func, int line) {
size_t szbuf = 0;
char buf[_LOG_MAX_HEAD_BUF_SIZE] = { 0 };
time_t t = time(NULL);
struct tm* time = localtime(&t);
struct _fill_head_parm parm = {
.level = level,
.buf = buf,
.szbuf = 0,
.mask = mask,
.file = file,
.mode = mode,
.func = func,
.line = line,
.time = time
};
size_t(*callback[3])(struct _fill_head_parm* parm) = {
_log_fill_head_time_ymd,
_log_fill_head_time_hms,
_log_fill_head_detail
};
for (int i = 0; i < sizeof(callback) / sizeof(callback[0]); i++) {
szbuf += (*callback[i])(&parm);
parm.buf[szbuf] = '|';
parm.szbuf = szbuf + 1;
}
if (LOG_MASK_ENDLINE & mask) szbuf += sprintf(buf, "\n");
buf[szbuf] = '\0';
szbuf += 1;
if (szlog <= szbuf) return 0;
strncpy(log, buf, szbuf);
return szbuf;
}
extern void log_buf(void);
size_t log_fill_head_str(int level, char* log, size_t szlog,
log_mask_t mask, const char* file, const char* mode, const char* func, int line);
#ifdef __cplusplus
}
#endif
/*
* Copyright (c) 2020 rxi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#endif /* _LLOG_H_ */

View File

@ -4,7 +4,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sysenv.h"
#include <sysenv.h>
#if _OS_WIN
#define WIN_PART 1
@ -24,6 +25,17 @@
#ifndef strncasecmp
#define strncasecmp _strnicmp
#endif
#ifndef SHUT_RD
#define SHUT_RD SD_RECEIVE
#endif
#ifndef SHUT_WR
#define SHUT_WR SD_SEND
#endif
#ifndef SHUT_RDWR
#define SHUT_RDWR SD_BOTH
#endif
//#define socklen_t int
#elif LINUX_PART
#include <unistd.h>
@ -96,6 +108,7 @@ static inline int sock_connect(SOCKET sock, const char* connect_ip, unsigned sho
static inline int sock_bind(SOCKET sock, const char* server_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 _sock(SOCKET* sock, int af, int type);
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); }
@ -108,7 +121,6 @@ static inline int _connect(SOCKET sock, struct addrinfo* resaddr);
static inline int _bind(SOCKET sock, struct addrinfo* resaddr);
static inline int _bindlisten(SOCKET sock, struct addrinfo* resaddr);
static inline int _accept(SOCKET sock, SOCKET* client, struct addrinfo* inf);
static inline int _sock(SOCKET* sock, int af, int type);
//not recommand and it will be remove
static inline int make_sock(SOCKET* sock) { return make_sock_tcp4(sock); };
@ -148,7 +160,7 @@ static inline int _sock_eai_res_map(int res) {
// need to using freeaddrinfo to free <resaddr>
static inline int _getaddrinfo(struct addrinfo* inf, struct addrinfo** resaddr,
const char* ip, const char* port) {
if (resaddr == NULL) { return ERR_SOCK_NULLPTR; }
if (resaddr == NULL || ip == NULL || port == NULL) { return ERR_SOCK_NULLPTR; }
int res = getaddrinfo(ip, port, inf, resaddr);
if (res != 0) {
return -(_sock_eai_res_map(res));
@ -290,20 +302,20 @@ static inline int sock_accpet(SOCKET sock,SOCKET* client, char** accept_ip, unsi
}
static inline int make_server_sock(SOCKET* sock, const char* server_ip, unsigned short port) {
struct addrinfo* resaddr = NULL;
char buf[8] = { 0 };
sprintf(buf, "%u", port);
int res = make_server_sock_ex(sock, server_ip, buf, &resaddr);
if (resaddr) freeaddrinfo(resaddr);
int res = make_server_sock_ex(sock, server_ip, buf, NULL);
return res;
}
static inline int make_client_sock(SOCKET* sock, const char* connect_ip, unsigned short port) {
struct addrinfo* resaddr = NULL;
char buf[8] = { 0 };
sprintf(buf, "%u", port);
int res = make_client_sock_ex(sock, connect_ip, buf, &resaddr);
if (resaddr) freeaddrinfo(resaddr);
int res = make_client_sock_ex(sock, connect_ip, buf, NULL);
if (res != ERR_SOCK_SUCCESS) {
return res;
}
res = sock_connect(*sock, connect_ip, port);
return res;
}
@ -322,14 +334,23 @@ static inline int make_server_sock_ex(SOCKET* sock, const char* server_ip, const
#endif
int res = ERR_SOCK_SUCCESS;
struct addrinfo inf = { 0 };
res = _getaddrinfo(&inf, resaddr, server_ip, port);
if (res != ERR_SOCK_SUCCESS) return res;
struct addrinfo* addr = NULL;
res = _getaddrinfo(&inf, &addr, server_ip, port);
if (res != ERR_SOCK_SUCCESS) goto END;
res = _socket(sock, *resaddr);
if (res != ERR_SOCK_SUCCESS) return res;
res = _socket(sock, addr);
if (res != ERR_SOCK_SUCCESS) goto END;
res = _bindlisten(*sock, *resaddr);
if (res != ERR_SOCK_SUCCESS) return res;
res = _bindlisten(*sock, addr);
if (res != ERR_SOCK_SUCCESS) goto END;
END:
if (resaddr == NULL) {
freeaddrinfo(addr);
}
else {
*resaddr = addr;
}
return res;
}
@ -348,15 +369,19 @@ static inline int make_client_sock_ex(SOCKET* sock, const char* connect_ip, cons
#endif
int res = ERR_SOCK_SUCCESS;
struct addrinfo inf = { 0 };
res = _getaddrinfo(&inf, resaddr, connect_ip, port);
if (res != ERR_SOCK_SUCCESS) return res;
struct addrinfo* addr = NULL;
res = _getaddrinfo(&inf, &addr, connect_ip, port);
if (res != ERR_SOCK_SUCCESS) goto END;
res = _socket(sock, *resaddr);
if (res != ERR_SOCK_SUCCESS) return res;
res = _socket(sock, addr);
if (res != ERR_SOCK_SUCCESS) goto END;
if (connect_ip) {
res = _connect(*sock, *resaddr);
if (res != ERR_SOCK_SUCCESS) return res;
END:
if (resaddr == NULL) {
freeaddrinfo(addr);
}
else {
*resaddr = addr;
}
return res;
}

26
include/tthreadpool.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef _TTHREAD_POOL_H_
#define _TTHREAD_POOL_H_
#include <sysenv.h>
#include <tthread.h>
#if _OS_WIN
#elif _OS_LINUX
#else
#error "Not Supported Operator System"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // _TTHREAD_POOL_H_

1
src/fifo.c Normal file
View File

@ -0,0 +1 @@
#include <bkfifo.h>

156
src/ini.c Normal file
View File

@ -0,0 +1,156 @@
#include <iini.h>
#include <stdio.h>
#include <string.h>
#if _OS_WIN
#ifndef strcasecmp
#define strcasecmp _stricmp
#endif
#ifndef strncasecmp
#define strncasecmp _strnicmp
#endif
#elif _OS_LINUX
#include <strings.h>
#else
#error "Not Supported Operator System"
#endif
#define INI_BUFFER_SIZE 512
static inline INICHAR* _ini_skip_leading(const INICHAR* str)
{
assert(str != NULL);
while ('\0' < *str && *str <= ' ')
str++;
return (INICHAR*)str;
}
static inline INICHAR* _ini_skip_trailing(const INICHAR* str, const INICHAR* base)
{
assert(str != NULL);
assert(base != NULL);
while (str > base && '\0' < *(str - 1) && *(str - 1) <= ' ')
str--;
return (INICHAR*)str;
}
static inline INICHAR* _ini_str_skip_trailing(INICHAR* str)
{
INICHAR* ptr = _ini_skip_trailing(strchr(str, '\0'), str);
assert(ptr != NULL);
*ptr = '\0';
return str;
}
void _ini_clean_string(INICHAR** start_pptr, INICHAR** end_pptr) {
/* Remove a trailing comment */
int is_string = 0;
*start_pptr = _ini_skip_leading(*end_pptr + 1);
for (*end_pptr = *start_pptr; **end_pptr != '#' && **end_pptr != ';' && **end_pptr != '\0'; *end_pptr += 1) {
if (**end_pptr == '"') {
if (*(*end_pptr + 1) == '"') {
*end_pptr += 1; /* skip "" (both quotes) */
}
else {
is_string = !is_string;/* single quote, toggle isstring */
}
}
else if (*(*end_pptr) == '\\' && *(*end_pptr + 1) == '"') {
*end_pptr += 1; /* skip \" (both quotes */
}
}
**end_pptr = ' ';
*end_pptr = _ini_skip_trailing(*end_pptr, *start_pptr);
**end_pptr = '\0';
/* Remove double quotes surrounding a value */
if (**start_pptr == '"' && *(*end_pptr - 1) == '"') {
*end_pptr -= 1;
*start_pptr += 1;
**end_pptr = '\0';
}
}
int _ini_str_get_section(INICHAR** start_pptr, INICHAR** end_pptr,
INICHAR* buf, size_t szbuf) {
*start_pptr = _ini_skip_leading(buf);
*end_pptr = strchr(buf, ']');
if (**start_pptr != '[' || *end_pptr == NULL) {
return -1;
}
/* When arrived here, a section was found; now optionally skip leading and
* trailing whitespace.
*/
assert(*start_pptr != NULL && **start_pptr == '[');
*start_pptr = _ini_skip_leading(*start_pptr + 1);
assert(*end_pptr != NULL && **end_pptr == ']');
*end_pptr = _ini_skip_trailing(*end_pptr, *start_pptr);
return 0;
}
int _ini_str_get_key(INICHAR** start_pptr, INICHAR** end_pptr,
INICHAR* buf, size_t szbuf) {
*start_pptr = _ini_skip_leading(buf);
if (**start_pptr == '[' || **start_pptr == '#' || **start_pptr == ':') return -1;
*end_pptr = strchr(*start_pptr, '='); /* Parse out the equal sign */
if (*end_pptr == NULL) *end_pptr = strchr(*start_pptr, ':');
if (*end_pptr == NULL) return -1;
return 0;
}
int _int_get_all_string(FILE* fp, const INICHAR* section, const INICHAR* key,
int idx_section, int idx_key, INICHAR* buf, size_t szbuf) {
int len = 0, idx = 0;
INICHAR* start_ptr, * end_ptr;
INICHAR local_buf[INI_BUFFER_SIZE] = { 0 };
assert(fp != NULL);
len = (section != NULL) ? (int)strlen(section) : 0;
/* Move through file 1 line at a time until a section is matched or EOF. If
* parameter Section is NULL, only look at keys above the first section. If
* idxSection is positive, copy the relevant section name.
*/
if (len > 0 || idx_section >= 0) {
assert(idx_section >= 0 || section != NULL);
idx = -1;
do {
if (fgets(local_buf, INI_BUFFER_SIZE, fp) == NULL) return -1;
if (_ini_str_get_section(&start_ptr, &end_ptr, local_buf, INI_BUFFER_SIZE) != 0) continue;
} while (!((int)(end_ptr - start_ptr) == len && section != NULL && strncasecmp(start_ptr, section, len) == 0));
}
/* Now that the section has been found, find the entry.
* Stop searching upon leaving the section's area.
*/
assert(key != NULL || idx_key >= 0);
len = (key != NULL) ? (int)strlen(key) : 0;
idx = -1;
do {
if (fgets(local_buf, INI_BUFFER_SIZE, fp) == NULL) return -1;
if (_ini_str_get_key(&start_ptr, &end_ptr, local_buf, INI_BUFFER_SIZE) != 0) continue;
} while (len != 0 && strncasecmp(start_ptr, key, len) != 0);
_ini_clean_string(&start_ptr, &end_ptr);
/* Copy up to BufferSize chars to buffer */
strncpy(buf, start_ptr, szbuf);
return 0;
}
int ini_get_str(const INICHAR* filename, const INICHAR* section, const INICHAR* key,
const INICHAR* def_vaule, INICHAR* buf, size_t szbuf) {
FILE* fp = NULL;
int res = -1;
if (fp = fopen(filename, "rb")) {
res = _int_get_all_string(fp, section, key, -1, -1, buf, szbuf);
fclose(fp);
}
if (res != 0) {
strncpy(buf, ((def_vaule == NULL) ? (const char*)"" : def_vaule), szbuf);
buf[szbuf] = '\0';
}
res = strlen(buf);
return res;
}

179
src/log.c Normal file
View File

@ -0,0 +1,179 @@
#include <llog.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#if _OS_WIN
#elif _OS_LINUX
#else
#error "Not Supported Operator System"
#endif
#define LOG_COLOR(code) \033\133##code##m
#define LOG_COLOR_TRACE LOG_COLOR(94)
#define LOG_COLOR_DEBUG LOG_COLOR(36)
#define LOG_COLOR_INFO LOG_COLOR(32)
#define LOG_COLOR_WARN LOG_COLOR(33)
#define LOG_COLOR_ERROR LOG_COLOR(31)
#define LOG_COLOR_FATAL LOG_COLOR(35)
#define LOG_MAX_HEAD_BUF_SIZE 256
#define _TO_STR(str) #str
#define TO_STR(str) _TO_STR(str)
static const char* _log_level_strings[] = {
"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
};
static const char* _log_level_colors[] = {
TO_STR(LOG_COLOR_TRACE), TO_STR(LOG_COLOR_DEBUG), TO_STR(LOG_COLOR_INFO),
TO_STR(LOG_COLOR_WARN), TO_STR(LOG_COLOR_ERROR), TO_STR(LOG_COLOR_FATAL)
};
struct _fill_head_parm {
int level;
char* buf;
size_t szbuf;
log_mask_t mask;
const char* file;
const char* mode;
const char* func;
int line;
struct tm* time;
};
size_t _log_fill_head_time_ymd(struct _fill_head_parm* parm) {
log_mask_t mask = parm->mask;
char* buf = parm->buf;
size_t szbuf = parm->szbuf;
struct tm* time = parm->time;
if (LOG_MASK_TIME_YMD & mask) {
if (LOG_MASK_YEAR & mask) {
szbuf += strftime(buf + szbuf, LOG_MAX_HEAD_BUF_SIZE - szbuf, "%Y", time);
}
else {
szbuf += sprintf(buf + szbuf, "Y");
}
if (LOG_MASK_MONTH & mask) {
szbuf += strftime(buf + szbuf, LOG_MAX_HEAD_BUF_SIZE - szbuf, "-%m", time);
}
else {
szbuf += sprintf(buf + szbuf, "-M");
}
if (LOG_MASK_DAY & mask) {
szbuf += strftime(buf + szbuf, LOG_MAX_HEAD_BUF_SIZE - szbuf, "-%d", time);
}
else {
szbuf += sprintf(buf + szbuf, "-D");
}
}
return szbuf;
}
size_t _log_fill_head_time_hms(struct _fill_head_parm* parm) {
log_mask_t mask = parm->mask;
char* buf = parm->buf;
size_t szbuf = parm->szbuf;
struct tm* time = parm->time;
if (LOG_MASK_TIME_HMS & mask) {
if (LOG_MASK_HOUR & mask) {
szbuf += strftime(buf + szbuf, LOG_MAX_HEAD_BUF_SIZE - szbuf, "%H", time);
}
else {
szbuf += sprintf(buf + szbuf, "h");
}
if (LOG_MASK_MINUTE & mask) {
szbuf += strftime(buf + szbuf, LOG_MAX_HEAD_BUF_SIZE - szbuf, ":%M", time);
}
else {
szbuf += sprintf(buf + szbuf, ":m");
}
if (LOG_MASK_SECOND & mask) {
szbuf += strftime(buf + szbuf, LOG_MAX_HEAD_BUF_SIZE - szbuf, ":%S", time);
}
else {
szbuf += sprintf(buf + szbuf, ":s");
}
}
return szbuf;
}
size_t _log_fill_head_detail(struct _fill_head_parm* parm) {
log_mask_t mask = parm->mask;
char* buf = parm->buf;
size_t szbuf = parm->szbuf;
int file_offset = 0;
if (LOG_MASK_COLORS & mask) {
szbuf += sprintf(buf + szbuf, "%s%-5s\033[0m \033[90m",
_log_level_colors[parm->level],
(LOG_MASK_LEVEL & mask) ? _log_level_strings[parm->level] : "nan");
}
else {
szbuf += sprintf(buf + szbuf, "%-5s ",
(LOG_MASK_LEVEL & mask) ? _log_level_strings[parm->level] : "nan");
}
if (LOG_FILE_SIMPLE & mask) {
for (file_offset = strlen(parm->file);
file_offset > -1; file_offset -= 1) {
if (parm->file[file_offset] == '/' || parm->file[file_offset] == '\\') {
file_offset += 1;
break;
}
}
}
szbuf += sprintf(buf + szbuf, "%.128s:%.32s:%.32s:%d:",
(LOG_MASK_FILE & mask) ? parm->file + file_offset : "file",
(LOG_MASK_MODE & mask) ? parm->mode : "mode",
(LOG_MASK_FUNC & mask) ? parm->func : "func",
(LOG_MASK_LINE & mask) ? parm->line : 0);
if (LOG_MASK_COLORS & mask) {
szbuf += sprintf(buf + szbuf, "\033[0m");
}
return szbuf;
}
size_t log_fill_head_str(int level, char* log, size_t szlog,
log_mask_t mask, const char* file, const char* mode, const char* func, int line) {
size_t szbuf = 0;
char buf[LOG_MAX_HEAD_BUF_SIZE] = { 0 };
time_t t = time(NULL);
struct tm* time = localtime(&t);
struct _fill_head_parm parm = {
.level = level,
.buf = buf,
.szbuf = 0,
.mask = mask,
.file = file,
.mode = mode,
.func = func,
.line = line,
.time = time
};
size_t(*callback[3])(struct _fill_head_parm* parm) = {
_log_fill_head_time_ymd,
_log_fill_head_time_hms,
_log_fill_head_detail
};
for (int i = 0; i < sizeof(callback) / sizeof(callback[0]); i++) {
szbuf += (*callback[i])(&parm);
parm.buf[szbuf] = '|';
parm.szbuf = szbuf + 1;
}
if (LOG_MASK_ENDLINE & mask) szbuf += sprintf(buf, "\n");
buf[szbuf] = '\0';
szbuf += 1;
if (szlog <= szbuf) return 0;
strncpy(log, buf, szbuf);
return szbuf;
}

0
src/mempool.c Normal file
View File

0
src/rbtree.c Normal file
View File

View File

@ -0,0 +1,3 @@
#include <tthreadpool.h>
#include <stdio.h>
#include <stdarg.h>

View File

@ -47,6 +47,9 @@ int main(int argc, char** argv)
if(getchar());
exit(-1);
}
if (Buf[strlen(Buf) - 1] == '\n') {
Buf[strlen(Buf) - 1] = '\0';
}
res = send(cfd, Buf, strlen(Buf) + 1, 0);
if (res == -1) {
printf("send error %s", Buf);

View File

@ -2,9 +2,15 @@ cmake_minimum_required(VERSION 3.22.1)
project(proj)
set(EXECUTABLE_OUTPUT_PATH ../)
add_subdirectory(server_proj server_proj)
add_subdirectory(client_proj client_proj)
set(C_STANDARD 99)
set(C_STANDARD_REQUIRED TRUE)
set(C_EXTENSIONS FALSE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin")
add_subdirectory(./server_proj server)
add_subdirectory(./client_proj client)
add_subdirectory(../../ zzylib)
# cmake ..
# cmake --build .

View File

@ -2,12 +2,13 @@ cmake_minimum_required(VERSION 3.22.1)
project(client_proj)
set(EXECUTABLE_OUTPUT_PATH ../../)
set(CMAKE_C_STANDARD 99)
include_directories(../../../include)
add_executable(client_proj client_proj.c)
set(C_STANDARD 99)
set(C_STANDARD_REQUIRED TRUE)
set(C_EXTENSIONS FALSE)
add_executable(${PROJECT_NAME} client_proj.c)
target_include_directories(${PROJECT_NAME} PUBLIC ../../../include)
target_link_libraries(${PROJECT_NAME} zzylib)
if(WIN32)
target_link_libraries(${PROJECT_NAME} wsock32 ws2_32)
endif()

View File

@ -3,58 +3,124 @@
#include <ssocket.h>
#include <tthread.h>
#include <iini.h>
#include <llog.h>
#define BUFFER_SIZE 128
SOCKET cfd;
MUTEX std_mutex;
char buf[BUFFER_SIZE];
const log_mask_t g_mask = LOG_MASK_BASE_DEFAULT;
#define _STR(str) #str
#define STR(str) _STR(str)
void receive_message(void* param)
{
printf("recv\n");
log_head_info_ex(buf, BUFFER_SIZE, "recv", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "recv start...\n");
int res = 0;
char Buf[1024] = { 0 };
while (1) {
res = recv(cfd, Buf, sizeof(Buf), 0);
if (res > 0 && res <= 1024) {
printf("[Recv]:%d,%s", res, Buf);
}
else {
if (res == -1 || res > sizeof(Buf)) {
log_head_error_ex(buf, BUFFER_SIZE, "receive", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "recv error %d\n", res);
break;
}
if (res == 0) {
log_head_info_ex(buf, BUFFER_SIZE, "receive", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "server close...\n");
break;
}
printf("server close connect, Close in three seconds\n");
sleeps(3);
else {
log_head_info_ex(buf, BUFFER_SIZE, "recv", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "[Recv]:%d,\"%s\"\n", res, Buf);
}
}
log_head_info_ex(buf, BUFFER_SIZE, "recv", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "press enter to exit\n");
if (getchar());
exit(-1);
// return NULL;
}
void end(void) {
shutdown(cfd, SHUT_WR);
close_sock(cfd);
}
int main(int argc, char** argv)
{
int res;
char Buf[1024] = { 0 };
printf("connect server...\n");
res = make_client_sock(&cfd, _SOCKET_TEST_IP4, _SOCKET_TEST_PORT);
if (res != 0) {
printf("error client sock\nerror code:%d\npress enter to continue\n", res);
if(getchar());
exit(-1);
}
printf("conncet server success\n");
char param[2][BUFFER_SIZE] = { 0 };
char local_buf[BUFFER_SIZE] = { 0 };
int szlocal_buf = 0;
ini_get_str("client.ini", "base", "server_ip", _SOCKET_TEST_IP4, param[0], BUFFER_SIZE);
ini_get_str("client.ini", "base", "server_port", STR(_SOCKET_TEST_PORT), param[1], BUFFER_SIZE);
thread_mutex_init(&std_mutex);
struct addrinfo* addr_info = NULL;
res = make_client_sock_ex(&cfd, param[0], param[1], &addr_info);
atexit(end);
if (res != 0) {
log_head_fatal_ex(buf, BUFFER_SIZE, "ssocket", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "client start error... press enter to continue\n");
if (getchar());
return res;
}
CONNECT:
res = _connect(cfd, addr_info);
if (res != 0) {
log_head_error_ex(buf, BUFFER_SIZE, "ssocket", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "connect server error, press enter to exit\n");
if(getchar());
goto CONNECT;
}
freeaddrinfo(addr_info);
log_head_info_ex(buf, BUFFER_SIZE, "ssocket", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "conncet server success... [%s:%s]\n", param[0], param[1]);
thread_create(NULL, receive_message, NULL);
while (1) {
fgets(Buf, sizeof(Buf), stdin);
if (strncasecmp(Buf, "exit", strlen("exit")) == 0) {
printf("press enter to continue\n");
fgets(local_buf, BUFFER_SIZE, stdin);
if (strncasecmp(local_buf, "exit", strlen("exit")) == 0) {
log_head_info_ex(buf, BUFFER_SIZE, "command", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "client exit... press enter to continue\n");
shutdown(cfd, SHUT_WR);
if(getchar());
exit(-1);
}
res = send(cfd, Buf, strlen(Buf) + 1, 0);
szlocal_buf = strlen(local_buf);
if (local_buf[szlocal_buf-1] == '\n') {
local_buf[szlocal_buf-1] = '\0';
}
else {
szlocal_buf += 1;
}
res = send(cfd, local_buf, szlocal_buf, 0);
if (res == -1) {
printf("send error %s", Buf);
printf("press enter to continue\n");
log_head_info_ex(buf, BUFFER_SIZE, "send", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "send error %s, press enter to continue\n", local_buf);
if(getchar());
exit(-1);
}
printf("[Buf]=%d,%s", res, Buf);
log_head_info_ex(buf, BUFFER_SIZE, "send", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "[send]=%d,\"%s\"\n", szlocal_buf, local_buf);
}
return 0;
}

View File

@ -2,12 +2,13 @@ cmake_minimum_required(VERSION 3.22.1)
project(server_proj)
set(EXECUTABLE_OUTPUT_PATH ../../)
set(CMAKE_C_STANDARD 99)
include_directories(../../../include)
add_executable(server_proj server_proj.c)
set(C_STANDARD 99)
set(C_STANDARD_REQUIRED TRUE)
set(C_EXTENSIONS FALSE)
add_executable(${PROJECT_NAME} server_proj.c)
target_include_directories(${PROJECT_NAME} PUBLIC ../../../include)
target_link_libraries(${PROJECT_NAME} zzylib)
if(WIN32)
target_link_libraries(${PROJECT_NAME} wsock32 ws2_32)
endif()

View File

@ -15,6 +15,9 @@ MUTEX std_mutex;
char buf[BUFFER_SIZE];
const log_mask_t g_mask = LOG_MASK_BASE_DEFAULT;
#define _STR(str) #str
#define STR(str) _STR(str)
void send_the_message(int sock, const char *Buff, int szBuf)
{
char Buf[2048] = {0};
@ -38,28 +41,36 @@ void receive_message(void* param)
free(param);
log_head_info_ex(buf, BUFFER_SIZE, "receive", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "recv start %d\n", sock);
tprintf(&std_mutex, "recv <%d> start...\n", sock);
while(1) {
res = recv(sock, Buf, sizeof(Buf), 0);
if(res == -1 || res > sizeof(Buf) || res == 0) {
if (res == -1 || res > sizeof(Buf)) {
log_head_error_ex(buf, BUFFER_SIZE, "receive", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "recv error %d\n", sock);
tprintf(&std_mutex, "recv error <%d>:%d\n", sock, res);
break;
}
if (res == 0) {
log_head_info_ex(buf, BUFFER_SIZE, "receive", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "client <%d> close...\n", sock);
break;
}
log_head_info_ex(buf, BUFFER_SIZE, "receive", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "recv buf:%d,%s", res, Buf);
tprintf(&std_mutex, "recv from <%d> buf[%d]:\"%s\"\n", sock, res, Buf);
send_the_message(sock, Buf, strlen(Buf)+1);
}
log_head_info_ex(buf, BUFFER_SIZE, "receive", g_mask);
tprintf(&std_mutex, buf);
shutdown(sock, SHUT_WR);
tprintf(&std_mutex, "socket <%d> exit\n", sock);
for(int i = 0; i < CLIENT_SIZE; i++) {
if(cfds[i] == sock) {
cfds[i] = 0;
}
}
close_sock(sock);
}
void acceptfunc(void* param) {
@ -78,6 +89,14 @@ void acceptfunc(void* param) {
if (sock_accpet(sfd, &sock, &ip, &port) != 0) {
continue;
}
psock = (SOCKET*)malloc(sizeof(SOCKET));
if (psock == NULL) {
log_head_fatal_ex(buf, BUFFER_SIZE, "accept", g_mask);
tprintf(&std_mutex, buf);
tprintf(&std_mutex, "malloc error... press enter to continue\n");
if (getchar());
exit(-1);
}
*psock = sock;
for(int i = 0; i < CLIENT_SIZE; i++) {
if(cfds[i] == 0) {
@ -98,8 +117,15 @@ void acceptfunc(void* param) {
}
}
#define _STR(str) #str
#define STR(str) _STR(str)
void end(void) {
shutdown(sfd, SHUT_WR);
close_sock(sfd);
for (int i = 0; i < CLIENT_SIZE; i++) {
if (cfds[i] != 0) {
close_sock(cfds[i]);
}
}
}
int main()
{
@ -108,10 +134,8 @@ int main()
ini_get_str("server.ini", "base", "server_port", STR(_SOCKET_TEST_PORT), param[1], BUFFER_SIZE);
thread_mutex_init(&std_mutex);
void* ptr = NULL;
int res = make_server_sock_ex(&sfd, param[0], param[1], &ptr);
freeaddrinfo(ptr);
int res = make_server_sock_ex(&sfd, param[0], param[1], NULL);
atexit(end);
if(res != 0) {
log_head_fatal_ex(buf, BUFFER_SIZE, "ssocket", g_mask);
tprintf(&std_mutex, buf);

View File

@ -88,7 +88,7 @@ int main()
int res = make_server_sock(&sfd, _SOCKET_TEST_IP6, _SOCKET_TEST_PORT);
if(res != 0) {
printf("server start error\npress enter to continue");
getchar();
if(getchar());
return 0;
}
printf("server start...\n");
@ -98,7 +98,7 @@ int main()
printf("%s", Buf);
if(strncasecmp(Buf, "exit", strlen("exit")) == 0) {
printf("exit success\npress enter to continue");
getchar();
if(getchar());
exit(-1);
}
}