Network module example.
#include <stdio.h>
#include <errno.h>
#define SERVER 0
#define CLIENT 1
fprintf(stderr,
" -a 'serveur address name/ip to bind (server mode) (optionnal)\n"
" -s 'serveur address name/ip to connect (client mode)\n"
" -p 'port': port to use, server or client\n"
" -u: use UDP transport instead of TCP\n"
" -i 'ipmode': optional, ip version to use. Default support both ipv4 and ipv6. Values: ipv4, ipv6\n"
" -n 'nb': optional, number of attempts (default: 3)\n"
" -h: show that help file\n"
" -v: show the program version\n"
" -V 'log level': optional, set the log level. Default: LOG_ERR, values: LOG_INFO, LOG_NOTICE, LOG_ERR, LOG_DEBUG\n");
}
if (argc == 1) {
fprintf(stderr, "No arguments given, help:\n");
exit(1);
}
while ((
getoptret = getopt(argc, argv,
"hvus:V:p:n:i:a:")) != EOF) {
case 'i':
if (!strcmp("v4", optarg)) {
} else if (!strcmp("v6", optarg)) {
} else {
}
break;
case 'v':
fprintf(stderr, "Date de compilation : %s a %s.\n", __DATE__, __TIME__);
exit(1);
case 'V':
if (!strncmp("LOG_NULL", optarg, 8)) {
} else {
if (!strncmp("LOG_NOTICE", optarg, 10)) {
} else {
if (!strncmp("LOG_INFO", optarg, 8)) {
} else {
if (!strncmp("LOG_ERR", optarg, 7)) {
} else {
if (!strncmp("LOG_DEBUG", optarg, 9)) {
} else {
fprintf(stderr, "%s n'est pas un niveau de log valide.\n", optarg);
exit(-1);
}
}
}
}
}
break;
case 'u':
(*udp_mode) = 1;
break;
case 's':
(*server) = strdup(optarg);
break;
case 'a':
(*address) = strdup(optarg);
break;
case 'n':
(*nb) = atoi(optarg);
break;
case 'p':
(*port) = strdup(optarg);
break;
default:
case '?': {
exit(1);
}
case 'h': {
exit(1);
}
}
}
}
int main(
int argc,
char** argv) {
char* srv = NULL;
exit(-1);
}
n_log(
LOG_ERR,
"Please specify only one of the following options: -a (server, addr to bind to) or -s (server on which to connect to)");
}
if (srv) {
} else {
}
#ifdef __linux__
exit(-1);
}
#endif
netw_unload();
exit(-1);
}
char buf[4096] = "";
struct sockaddr_storage client_addr;
socklen_t client_len = sizeof(client_addr);
memset(buf, 0, sizeof(buf));
client_len = sizeof(client_addr);
if (received > 0) {
buf[received] = '\0';
char client_ip[64] = "";
char client_port[16] = "";
getnameinfo((struct sockaddr*)&client_addr, client_len, client_ip, sizeof(client_ip), client_port, sizeof(client_port), NI_NUMERICHOST | NI_NUMERICSERV);
n_log(
LOG_NOTICE,
"UDP RECV from %s:%s: %s (%zd bytes)", client_ip, client_port, buf, received);
if (sent > 0) {
} else {
}
} else {
}
}
netw_unload();
exit(1);
}
char send_buf[256] = "";
snprintf(send_buf, sizeof(send_buf), "UDP Hello from client (attempt %d)", it);
if (sent > 0) {
} else {
continue;
}
char recv_buf[4096] = "";
if (received > 0) {
recv_buf[received] = '\0';
} else {
}
}
}
}
netw_unload();
exit(-1);
}
int it = 0;
} else {
int error = 0;
int pthread_error = 0;
errno = 0;
error = errno;
if (pthread_error != 0) {
n_log(
LOG_ERR,
"Error creating client management pthread:%d , error: %s", pthread_error, strerror(error));
netw_unload();
exit(-1);
}
}
}
int error = 0;
n_log(
LOG_ERR,
"Error adding client management to thread pool");
}
it++;
} else {
}
}
n_log(
LOG_NOTICE,
"Setting a 2s wait close timeout to wait for last datas to be received by peer (optional)");
netw_unload();
exit(1);
}
N_STR *sended_data = NULL, *recved_data = NULL, *hostname = NULL, *tmpstr = NULL;
if (tmpstr) {
n_log(
LOG_NOTICE,
"RECEIVED DATAS: %s - %s", recved_data ?
_nstr(recved_data) :
"NULL", hostname ?
_nstr(hostname) :
"NULL");
} else {
}
sleep(1);
}
}
netw_unload();
exit(0);
}
void process_args(int argc, char **argv)
THREAD_POOL * thread_pool
static NETWORK * netw_server
static pthread_t netw_thr
NETWORK * netw
Network for server mode, accepting incomming.
void * manage_client(void *ptr)
recv/send datas if any for the client
int get_net_datas(N_STR *str, N_STR **hostname, N_STR **data)
decode data we got from network
int send_net_datas(NETWORK *netw, N_STR *data)
send data to specified network
#define FreeNoLog(__ptr)
Free Handler without log.
#define _str(__PTR)
define true
int sigchld_handler_installer()
install signal SIGCHLD handler to reap zombie processes
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
#define LOG_NOTICE
normal but significant condition
#define LOG_NULL
no log output
#define LOG_INFO
informational
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
A box including a string and his lenght.
void u_sleep(unsigned int usec)
wrapper around usleep for API consistency
char * ip
ip of the connected socket
N_SOCKET link
networking socket
int netw_bind_udp(NETWORK **netw, char *addr, char *port, int ip_version)
Create a UDP bound socket for receiving datagrams.
#define NETWORK_IPV6
Flag to force IPV6
int netw_make_listening(NETWORK **netw, char *addr, char *port, int nbpending, int ip_version)
Make a NETWORK be a Listening network.
ssize_t send_udp_data(void *netw, char *buf, uint32_t n)
send data via UDP on a connected socket
int netw_start_thr_engine(NETWORK *netw)
Start the NETWORK netw Threaded Engine.
#define NETWORK_IPV4
Flag to force IPV4
ssize_t netw_udp_sendto(NETWORK *netw, char *buf, uint32_t n, struct sockaddr *dest_addr, socklen_t dest_len)
send data via UDP to a specific destination address
NETWORK * netw_accept_from_ex(NETWORK *from, size_t send_list_limit, size_t recv_list_limit, int blocking, int *retval)
make a normal 'accept' .
#define NETWORK_IPALL
Flag for auto detection by OS of ip version to use.
#define NETWORK_WAIT_CLOSE_TIMEOUT
Flag to set network closing wait timeout.
int netw_setsockopt(NETWORK *netw, int optname, int value)
Modify common socket options on the given netw.
ssize_t recv_udp_data(void *netw, char *buf, uint32_t n)
recv data via UDP from a connected socket
NETWORK * netw_accept_from(NETWORK *from)
make a normal blocking 'accept' .
int netw_close(NETWORK **netw)
Closing a specified Network, destroy queues, free the structure.
N_STR * netw_wait_msg(NETWORK *netw, unsigned int refresh, size_t timeout)
Wait a message from aimed NETWORK.
int netw_connect(NETWORK **netw, char *host, char *port, int ip_version)
Use this to connect a NETWORK to any listening one, unrestricted send/recv lists.
int netw_connect_udp(NETWORK **netw, char *host, char *port, int ip_version)
Connect a UDP socket to a remote host.
ssize_t netw_udp_recvfrom(NETWORK *netw, char *buf, uint32_t n, struct sockaddr *src_addr, socklen_t *src_len)
recv data via UDP and capture the source address
THREAD_POOL * new_thread_pool(size_t nbmaxthr, size_t nb_max_waiting)
Create a new pool of nbmaxthr threads.
int add_threaded_process(THREAD_POOL *thread_pool, void *(*func_ptr)(void *param), void *param, int mode)
add a function and params to a thread pool
int refresh_thread_pool(THREAD_POOL *thread_pool)
try to add some waiting DIRECT_PROCs on some free thread slots, else do nothing
int wait_for_threaded_pool(THREAD_POOL *thread_pool)
Wait for the thread pool to become idle (no active threads, empty waiting list), blocking without pol...
int destroy_threaded_pool(THREAD_POOL **pool, unsigned int delay)
delete a thread_pool, exit the threads and free the structs
#define DIRECT_PROC
processing mode for added func, direct start, not queued
Structure of a thread pool.