Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_gui_network.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
43#define WIDTH 800
44#define HEIGHT 600
45
46#define ALLEGRO_UNSTABLE 1
47
48#include <getopt.h>
49#include <sys/time.h>
50#include <sys/types.h>
51
52#include "nilorea/n_common.h"
53#include "nilorea/n_log.h"
54#include "nilorea/n_str.h"
55#include "nilorea/n_time.h"
56#include "nilorea/n_network.h"
58#include "nilorea/n_gui.h"
59
60/* custom message type for chat text */
61#define NETMSG_CHAT 100
62
63ALLEGRO_DISPLAY* display = NULL;
64
65static int DONE = 0;
66static int mode = -1; /* 0 = server, 1 = client */
67static char* server_addr = NULL;
68static char* port_str = NULL;
69
70/* networking */
71static NETWORK* netw_server = NULL;
72static NETWORK* netw_client = NULL;
73static NETWORK_POOL* pool = NULL;
74
75/* gui widget ids */
76static int win_chat = -1;
77static int lbl_status = -1;
78static int listbox_log = -1;
79static int textarea_input = -1;
80static int btn_send = -1;
81
82/* server-only gui widget ids */
83static int win_clients = -1;
84static int lbl_clients_header = -1;
85static int listbox_clients = -1;
86
87static N_GUI_CTX* gui = NULL;
88
93void chat_log_add(const char* text) {
94 if (gui && listbox_log >= 0) {
96 }
97}
98
103 if (!gui || listbox_clients < 0 || !pool) return;
104
106
107 HT_FOREACH(node, pool->pool, {
108 NETWORK* cn = (NETWORK*)node->data.ptr;
109 if (cn) {
110 char entry[256] = "";
111 snprintf(entry, sizeof(entry), "%s:%s (sock %d)",
112 cn->link.ip ? cn->link.ip : "?",
113 cn->link.port ? cn->link.port : "?",
114 (int)cn->link.sock);
115 n_gui_listbox_add_item(gui, listbox_clients, entry);
116 }
117 });
118
119 char header[64] = "";
120 snprintf(header, sizeof(header), "Connected clients: %zu", netw_pool_nbclients(pool));
121 if (lbl_clients_header >= 0) {
123 }
124}
125
131N_STR* build_chat_msg(const char* text) {
132 NETW_MSG* msg = NULL;
133 create_msg(&msg);
134 if (!msg) return NULL;
135
137 add_strdup_to_msg(msg, text);
138
139 N_STR* str = make_str_from_msg(msg);
140 delete_msg(&msg);
141 return str;
142}
143
150int decode_chat_msg(N_STR* str, char** out_text) {
151 NETW_MSG* msg = NULL;
152 int type = 0;
153 int ok = FALSE;
154
155 if (out_text) {
156 *out_text = NULL;
157 }
158
159 msg = make_msg_from_str(str);
160 if (!msg) {
161 return FALSE;
162 }
163
164 if (!get_int_from_msg(msg, &type)) {
165 delete_msg(&msg);
166 return FALSE;
167 }
168
169 if (type != NETMSG_CHAT) {
170 delete_msg(&msg);
171 return FALSE;
172 }
173
174 ok = get_str_from_msg(msg, out_text);
175 if (!ok && out_text) {
176 *out_text = NULL;
177 }
178
179 delete_msg(&msg);
180 return ok;
181}
182
188void on_send_click(int widget_id, void* user_data) {
189 (void)widget_id;
190 (void)user_data;
191
192 const char* text = n_gui_textarea_get_text(gui, textarea_input);
193 if (!text || text[0] == '\0') return;
194
195 N_STR* msg_str = build_chat_msg(text);
196 if (!msg_str) return;
197
198 if (mode == 0 && pool) {
199 /* server: broadcast to all clients */
200 netw_pool_broadcast(pool, NULL, msg_str);
201 char logbuf[512] = "";
202 snprintf(logbuf, sizeof(logbuf), "[server] %s", text);
203 chat_log_add(logbuf);
204 } else if (mode == 1 && netw_client) {
205 N_STR* copy = nstrdup(msg_str);
206 if (!netw_add_msg(netw_client, copy)) {
207 /* netw_add_msg did not take ownership of 'copy' on failure */
208 free_nstr(&copy);
209 }
210 char logbuf[512] = "";
211 snprintf(logbuf, sizeof(logbuf), "[me] %s", text);
212 chat_log_add(logbuf);
213 }
214 free_nstr(&msg_str);
216}
217
223void poll_network_msgs(NETWORK* netw, const char* prefix) {
224 if (!netw) return;
225 N_STR* incoming = NULL;
226 while ((incoming = netw_get_msg(netw)) != NULL) {
227 char* text = NULL;
228 if (decode_chat_msg(incoming, &text) == TRUE && text) {
229 char logbuf[512] = "";
230 snprintf(logbuf, sizeof(logbuf), "[%s] %s", prefix, text);
231 chat_log_add(logbuf);
232
233 /* server: relay to all other clients */
234 if (mode == 0 && pool) {
235 N_STR* relay = build_chat_msg(text);
236 if (relay) {
238 free_nstr(&relay);
239 }
240 }
241 Free(text);
242 }
243 free_nstr(&incoming);
244 }
245}
246
247void usage(void) {
248 fprintf(stderr,
249 "Usage:\n"
250 " Server: ex_gui_network -p PORT\n"
251 " Client: ex_gui_network -s ADDRESS -p PORT\n"
252 " Options:\n"
253 " -s addr : server address to connect to (client mode)\n"
254 " -p port : port number\n"
255 " -V level : log level (LOG_DEBUG, LOG_INFO, LOG_ERR)\n"
256 " -h : help\n");
257}
258
259int main(int argc, char** argv) {
260 int log_level = LOG_ERR;
261 int getoptret = 0;
262
263 while ((getoptret = getopt(argc, argv, "hs:p:V:")) != EOF) {
264 switch (getoptret) {
265 case 's':
266 server_addr = strdup(optarg);
267 break;
268 case 'p':
269 port_str = strdup(optarg);
270 break;
271 case 'V':
272 if (!strcmp("LOG_DEBUG", optarg))
274 else if (!strcmp("LOG_INFO", optarg))
276 else if (!strcmp("LOG_NOTICE", optarg))
278 else if (!strcmp("LOG_ERR", optarg))
280 break;
281 default:
282 case 'h':
283 usage();
284 exit(1);
285 }
286 }
288
289 if (!port_str) {
290 fprintf(stderr, "Port is required. Use -p PORT\n");
291 usage();
292 exit(1);
293 }
294
295 mode = server_addr ? 1 : 0;
296
297 /* allegro init */
298 if (!al_init()) {
299 n_log(LOG_ERR, "al_init failed");
300 return 1;
301 }
302 al_install_keyboard();
303 al_install_mouse();
304 al_init_primitives_addon();
305 al_init_font_addon();
306 al_init_ttf_addon();
307 al_init_image_addon();
308
309 al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_WINDOWED);
310 display = al_create_display(WIDTH, HEIGHT);
311 if (!display) {
312 n_log(LOG_ERR, "Failed to create display");
313 return 1;
314 }
315 al_set_window_title(display, mode == 0 ? "GUI Network - Server" : "GUI Network - Client");
316
317 ALLEGRO_FONT* font = al_create_builtin_font();
318 ALLEGRO_EVENT_QUEUE* event_queue = al_create_event_queue();
319 ALLEGRO_TIMER* timer = al_create_timer(1.0 / 30.0);
320
321 al_register_event_source(event_queue, al_get_display_event_source(display));
322 al_register_event_source(event_queue, al_get_keyboard_event_source());
323 al_register_event_source(event_queue, al_get_mouse_event_source());
324 al_register_event_source(event_queue, al_get_timer_event_source(timer));
325
326 /* create GUI */
327 gui = n_gui_new_ctx(font);
328 n_gui_set_display_size(gui, (float)WIDTH, (float)HEIGHT);
329
330 /* main chat window */
331 win_chat = n_gui_add_window(gui, mode == 0 ? "Chat Server" : "Chat Client", 10, 10, 780, 580);
333
334 /* status label */
335 lbl_status = n_gui_add_label(gui, win_chat, mode == 0 ? "Server: waiting..." : "Client: connecting...",
336 10, 10, 760, 20, N_GUI_ALIGN_LEFT);
337
338 /* chat log listbox */
339 listbox_log = n_gui_add_listbox(gui, win_chat, 10, 40, 760, 420, N_GUI_SELECT_NONE, NULL, NULL);
340
341 /* input textarea */
342 textarea_input = n_gui_add_textarea(gui, win_chat, 10, 470, 660, 30, 0, 256, NULL, NULL);
343
344 /* send button bound to Enter key (works even while typing in the single-line text input) */
345 btn_send = n_gui_add_button(gui, win_chat, "Send", 680, 470, 90, 30, N_GUI_SHAPE_ROUNDED, on_send_click, NULL);
346 n_gui_button_set_keycode(gui, btn_send, ALLEGRO_KEY_ENTER, 0);
347
348 /* server: connected clients window */
349 if (mode == 0) {
350 win_clients = n_gui_add_window(gui, "Connected Clients", 800, 10, 290, 580);
352
353 lbl_clients_header = n_gui_add_label(gui, win_clients, "Connected clients: 0",
354 10, 10, 270, 20, N_GUI_ALIGN_LEFT);
355
356 listbox_clients = n_gui_add_listbox(gui, win_clients, 10, 40, 270, 500, N_GUI_SELECT_NONE, NULL, NULL);
357 }
358
359 /* network setup */
360 int net_ok = FALSE;
361 if (mode == 0) {
362 /* server */
363 pool = netw_new_pool(128);
364 if (!pool) {
365 n_gui_label_set_text(gui, lbl_status, "Server: memory allocation failed");
366 chat_log_add("Failed to allocate server connection pool");
367 } else if (netw_make_listening(&netw_server, NULL, port_str, 10, NETWORK_IPALL) == TRUE) {
369 net_ok = TRUE;
370 char buf[128] = "";
371 snprintf(buf, sizeof(buf), "Server listening on port %s", port_str);
373 chat_log_add(buf);
374 } else {
375 n_gui_label_set_text(gui, lbl_status, "Server: bind failed");
376 chat_log_add("Failed to bind server socket");
377 }
378 } else {
379 /* client */
382 net_ok = TRUE;
383 char buf[128] = "";
384 snprintf(buf, sizeof(buf), "Connected to %s:%s", server_addr, port_str);
386 chat_log_add(buf);
387 } else {
388 n_gui_label_set_text(gui, lbl_status, "Client: connection failed");
389 chat_log_add("Failed to connect to server");
390 }
391 }
392
393 al_start_timer(timer);
394 int redraw = 1;
395
396 while (!DONE) {
397 ALLEGRO_EVENT ev;
398 al_wait_for_event(event_queue, &ev);
399
400 if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
401 DONE = 1;
402 continue;
403 }
404 if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
405 DONE = 1;
406 continue;
407 }
408 if (ev.type == ALLEGRO_EVENT_TIMER) {
409 redraw = 1;
410
411 /* server: accept new connections */
412 if (mode == 0 && net_ok && netw_server) {
413 int retval = 0;
414 NETWORK* new_client = netw_accept_from_ex(netw_server, 0, 0, -1, &retval);
415 if (new_client) {
416 netw_start_thr_engine(new_client);
417 if (netw_pool_add(pool, new_client) != TRUE) {
418 /* Failed to track this client in the pool: close it to avoid leaks */
419 chat_log_add("Failed to add new client to pool, closing connection");
420 netw_close(&new_client);
421 } else {
422 char buf[128] = "";
423 snprintf(buf, sizeof(buf), "Client connected from %s (total: %zu)",
424 new_client->link.ip ? new_client->link.ip : "?",
426 chat_log_add(buf);
429 }
430 }
431 }
432
433 /* poll messages */
434 if (mode == 0 && pool) {
435 /* server: poll each client in pool */
436 LIST* dead_clients = new_generic_list(MAX_LIST_ITEMS);
437 if (!dead_clients) {
438 n_log(LOG_ERR, "Could not allocate dead_clients list");
439 } else {
440 HT_FOREACH(node, pool->pool, {
441 NETWORK* cn = (NETWORK*)node->data.ptr;
442 if (cn) {
443 uint32_t state = 0;
444 int thr_state = 0;
445 netw_get_state(cn, &state, &thr_state);
446 if (state & NETW_EXITED || state & NETW_ERROR || state & NETW_EXIT_ASKED) {
447 list_push(dead_clients, cn, NULL);
448 } else {
449 poll_network_msgs(cn, cn->link.ip ? cn->link.ip : "client");
450 }
451 }
452 });
453 /* remove and close dead connections outside of the iteration */
454 int had_dead = 0;
455 list_foreach(dead_node, dead_clients) {
456 NETWORK* cn = (NETWORK*)dead_node->ptr;
457 char disc_buf[128] = "";
458 snprintf(disc_buf, sizeof(disc_buf), "Client %s:%s disconnected",
459 cn->link.ip ? cn->link.ip : "?",
460 cn->link.port ? cn->link.port : "?");
461 chat_log_add(disc_buf);
463 netw_close(&cn);
464 had_dead = 1;
465 }
466 if (had_dead) {
468 char sbuf[64] = "";
469 snprintf(sbuf, sizeof(sbuf), "Connected clients: %zu", netw_pool_nbclients(pool));
471 }
472 list_destroy(&dead_clients);
473 }
474 } else if (mode == 1 && netw_client) {
476 /* check connection status */
477 uint32_t state = 0;
478 int thr_state = 0;
479 netw_get_state(netw_client, &state, &thr_state);
480 if (state & NETW_EXITED || state & NETW_ERROR) {
481 n_gui_label_set_text(gui, lbl_status, "Disconnected from server");
482 chat_log_add("Disconnected from server");
484 }
485 }
486 }
487
489
490 if (redraw && al_is_event_queue_empty(event_queue)) {
491 redraw = 0;
492 al_clear_to_color(al_map_rgb(40, 40, 50));
494 al_flip_display();
495 }
496 }
497
498 /* cleanup */
499 if (netw_client) {
501 }
502 if (pool) {
503 /* netw_destroy_pool() does not close NETWORK objects; its internal
504 * destroy callback only logs. Collect all pool clients first, then
505 * close each one (netw_close also removes the client from the pool
506 * via netw_pool_remove), and finally destroy the now-empty pool. */
507 LIST* clients_to_close = new_generic_list(UNLIMITED_LIST_ITEMS);
508 if (clients_to_close) {
509 HT_FOREACH(node, pool->pool, {
510 NETWORK* cn = (NETWORK*)node->data.ptr;
511 if (cn) {
512 list_push(clients_to_close, cn, NULL);
513 }
514 });
515 list_foreach(cnode, clients_to_close) {
516 NETWORK* cn = (NETWORK*)cnode->ptr;
517 netw_close(&cn);
518 }
519 list_destroy(&clients_to_close);
520 } else {
521 n_log(LOG_ERR, "failed to allocate client list for pool cleanup; pool clients may leak");
522 }
524 }
525 if (netw_server) {
527 }
528 netw_unload();
529
531 al_destroy_font(font);
532 al_destroy_timer(timer);
533 al_destroy_event_queue(event_queue);
534 al_destroy_display(display);
535
538
539 return 0;
540}
static void usage(void)
int main(void)
int getoptret
Definition ex_fluid.c:59
int DONE
Definition ex_fluid.c:58
int log_level
Definition ex_fluid.c:60
ALLEGRO_DISPLAY * display
Definition ex_fluid.c:54
#define WIDTH
Definition ex_gui.c:42
static int lbl_status
Definition ex_gui.c:70
#define HEIGHT
Definition ex_gui.c:43
static N_GUI_CTX * gui
N_STR * build_chat_msg(const char *text)
build a chat network message
static NETWORK * netw_server
static int mode
static int textarea_input
static int win_clients
void poll_network_msgs(NETWORK *netw, const char *prefix)
process incoming messages on a single network connection
void refresh_clients_list(void)
refresh the connected clients listbox (server only)
#define NETMSG_CHAT
static int win_chat
static int listbox_log
static char * server_addr
static int lbl_clients_header
void on_send_click(int widget_id, void *user_data)
send button callback
static NETWORK * netw_client
static char * port_str
void chat_log_add(const char *text)
add a line to the chat log listbox
static int listbox_clients
static int btn_send
static NETWORK_POOL * pool
int decode_chat_msg(N_STR *str, char **out_text)
decode a received chat message
NETWORK * netw
Network for server mode, accepting incomming.
Definition ex_network.c:39
#define FreeNoLog(__ptr)
Free Handler without log.
Definition n_common.h:272
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:263
void n_gui_set_display_size(N_GUI_CTX *ctx, float w, float h)
Set the display (viewport) size for global scrollbar computation.
Definition n_gui.c:9034
#define N_GUI_ALIGN_LEFT
left aligned text
Definition n_gui.h:189
void n_gui_textarea_set_text(N_GUI_CTX *ctx, int widget_id, const char *text)
set the text content of a textarea widget
Definition n_gui.c:3263
void n_gui_label_set_text(N_GUI_CTX *ctx, int widget_id, const char *text)
set the text of a label widget
Definition n_gui.c:4511
int n_gui_add_listbox(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, int selection_mode, void(*on_select)(int, int, int, void *), void *user_data)
Add a listbox widget.
Definition n_gui.c:2620
int n_gui_process_event(N_GUI_CTX *ctx, ALLEGRO_EVENT event)
Process an allegro event through the GUI system.
Definition n_gui.c:9836
int n_gui_add_label(N_GUI_CTX *ctx, int window_id, const char *text, float x, float y, float w, float h, int align)
Add a static text label.
Definition n_gui.c:2966
#define N_GUI_WIN_FIXED_POSITION
disable window dragging (default:enable)
Definition n_gui.h:231
#define N_GUI_SELECT_NONE
no selection allowed (display only)
Definition n_gui.h:173
int n_gui_listbox_add_item(N_GUI_CTX *ctx, int widget_id, const char *text)
add an item to a listbox widget
Definition n_gui.c:3371
void n_gui_draw(N_GUI_CTX *ctx)
Draw all visible windows and their widgets.
Definition n_gui.c:8542
void n_gui_button_set_keycode(N_GUI_CTX *ctx, int widget_id, int keycode, int modifiers)
Bind a keyboard key with optional modifier requirements to a button.
Definition n_gui.c:2411
int n_gui_add_window(N_GUI_CTX *ctx, const char *title, float x, float y, float w, float h)
Add a new pseudo-window to the context.
Definition n_gui.c:1063
N_GUI_CTX * n_gui_new_ctx(ALLEGRO_FONT *default_font)
Create a new GUI context.
Definition n_gui.c:903
void n_gui_listbox_clear(N_GUI_CTX *ctx, int widget_id)
remove all items from a listbox widget
Definition n_gui.c:3418
void n_gui_destroy_ctx(N_GUI_CTX **ctx)
Destroy a GUI context and all its windows/widgets.
Definition n_gui.c:995
const char * n_gui_textarea_get_text(N_GUI_CTX *ctx, int widget_id)
get the text content of a textarea widget
Definition n_gui.c:3249
#define N_GUI_SHAPE_ROUNDED
rounded rectangle shape
Definition n_gui.h:149
void n_gui_window_set_flags(N_GUI_CTX *ctx, int window_id, int flags)
Set feature flags on a window.
Definition n_gui.c:1968
int n_gui_add_textarea(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, int multiline, size_t char_limit, void(*on_change)(int, const char *, void *), void *user_data)
Add a text area widget.
Definition n_gui.c:2498
int n_gui_add_button(N_GUI_CTX *ctx, int window_id, const char *label, float x, float y, float w, float h, int shape, void(*on_click)(int, void *), void *user_data)
Add a button widget to a window.
Definition n_gui.c:2124
#define N_GUI_WIN_RESIZABLE
enable user-resizable window with a drag handle at bottom-right
Definition n_gui.h:229
The top-level GUI context that holds all windows.
Definition n_gui.h:1354
#define HT_FOREACH(__ITEM_, __HASH_,...)
ForEach macro helper.
Definition n_hash.h:216
#define UNLIMITED_LIST_ITEMS
flag to pass to new_generic_list for an unlimited number of item in the list.
Definition n_list.h:73
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper, safe for node removal during iteration.
Definition n_list.h:89
int list_destroy(LIST **list)
Empty and Free a list container.
Definition n_list.c:548
LIST * new_generic_list(size_t max_items)
Initialiaze a generic list container to max_items pointers.
Definition n_list.c:37
#define MAX_LIST_ITEMS
flag to pass to new_generic_list for the maximum possible number of item in a list
Definition n_list.h:75
Structure of a generic LIST container.
Definition n_list.h:59
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_DEBUG
debug-level messages
Definition n_log.h:84
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_NOTICE
normal but significant condition
Definition n_log.h:80
#define LOG_INFO
informational
Definition n_log.h:82
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:203
N_STR * nstrdup(N_STR *str)
Duplicate a N_STR.
Definition n_str.c:716
A box including a string and his lenght.
Definition n_str.h:61
int get_str_from_msg(NETW_MSG *msg, char **value)
Get a string from a message string list.
int add_strdup_to_msg(NETW_MSG *msg, const char *str)
Add a copy of char *str to the string list in the message.
NETW_MSG * make_msg_from_str(N_STR *str)
Make a single message of the string.
N_STR * make_str_from_msg(NETW_MSG *msg)
Make a single string of the message.
int create_msg(NETW_MSG **msg)
Create a NETW_MSG *object.
int add_int_to_msg(NETW_MSG *msg, int value)
Add an int to the int list int the message.
int delete_msg(NETW_MSG **msg)
Delete a NETW_MSG *object.
int get_int_from_msg(NETW_MSG *msg, int *value)
Get an int from a message int list.
network message, array of char and int
char * ip
ip of the connected socket
Definition n_network.h:295
N_SOCKET link
networking socket
Definition n_network.h:388
char * port
port of socket
Definition n_network.h:291
HASH_TABLE * pool
table of clients
Definition n_network.h:561
N_STR * netw_get_msg(NETWORK *netw)
Get a message from aimed NETWORK.
Definition n_network.c:3666
int netw_add_msg(NETWORK *netw, N_STR *msg)
Add a message to send in aimed NETWORK.
Definition n_network.c:3569
NETWORK_POOL * netw_new_pool(size_t nb_min_element)
return a new network pool of nb_min_element
Definition n_network.c:4983
int netw_make_listening(NETWORK **netw, char *addr, char *port, int nbpending, int ip_version)
Make a NETWORK be a Listening network.
Definition n_network.c:2885
int netw_start_thr_engine(NETWORK *netw)
Start the NETWORK netw Threaded Engine.
Definition n_network.c:3740
int netw_destroy_pool(NETWORK_POOL **netw_pool)
free a NETWORK_POOL *pool
Definition n_network.c:5002
size_t netw_pool_nbclients(NETWORK_POOL *netw_pool)
return the number of networks in netw_pool
Definition n_network.c:5141
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' .
Definition n_network.c:3358
#define NETWORK_IPALL
Flag for auto detection by OS of ip version to use.
Definition n_network.h:48
int netw_pool_broadcast(NETWORK_POOL *netw_pool, const NETWORK *from, N_STR *net_msg)
add net_msg to all network in netork pool
Definition n_network.c:5117
int netw_get_state(NETWORK *netw, uint32_t *state, int *thr_engine_status)
Get the state of a network.
Definition n_network.c:2532
int netw_close(NETWORK **netw)
Closing a specified Network, destroy queues, free the structure.
Definition n_network.c:2662
int netw_set_blocking(NETWORK *netw, unsigned long int is_blocking)
Modify blocking socket mode.
Definition n_network.c:909
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.
Definition n_network.c:2359
int netw_pool_add(NETWORK_POOL *netw_pool, NETWORK *netw)
add a NETWORK *netw to a NETWORK_POOL *pool
Definition n_network.c:5034
int netw_pool_remove(NETWORK_POOL *netw_pool, NETWORK *netw)
remove a NETWORK *netw to a NETWORK_POOL *pool
Definition n_network.c:5080
@ NETW_EXITED
Definition n_network.h:283
@ NETW_ERROR
Definition n_network.h:283
Structure of a NETWORK.
Definition n_network.h:309
structure of a network pool
Definition n_network.h:559
Common headers and low-level functions & define.
GUI system: buttons, sliders, text areas, checkboxes, scrollbars, dropdown menus, windows.
Generic log system.
Network Engine.
Network messages , serialization tools.
N_STR and string function declaration.
Timing utilities.