TCP Socket (af_inet)(IPv4/IPv6)(with ssl) – c language

This program is an example of programming a TCP socket in C language, using the well-known client-server programming model.
The server side is multi-threaded, but the thread is optional since the developer/designer is still responsible for deciding if he/she needs it.

The library “commv6.c” develops all the functions to create, bind, listen, and remove a socket AF_INET, and the functions to send and receive messages (using the methods read and write). It supports: IPv4/IPv6 and SSL (see commSSL.c).
The structure of a message is defined in the file “msg.h”.

Code tested under debian-like and arch linux platform (thanks to nignux).


Questo programma è un esempio di programmazione di un socket TCP in linguaggio C, utilizzando il ben noto paradigma di programmazione client-server.
Il lato server è multi-threaded, ma è del tutto opzionale, e sarà responsabilità dello sviluppatore decidere se ne ha bisogno.

La libreria “commv6.c” sviluppa tutte le funzioni per creare, pubblicare, rimanere in ascolto e rimuovere una  socket af_inet, e le funzioni per inviare e ricevere messaggi (usando i metodi read e write). Il codice supporta socket ipv4/ipv6 e SSL (commSSL.c)
La struttura di un messaggio è definita nel file “msg.h”.

Codice testato sotto piattaforma debian-like e arch linux (ringraziamenti a nignux).


Be careful when you do a read(/write) on a socket: the machine at the other end of the socket is of your own platform (x86/x64)?
Fate attenzione quando fate una read(/write) su una socket: la macchina dall’altro capo della socket è della vostra stessa piattaforma (x86/x64)?
x86 x64
sizeof(char)  1  1
sizeof(short)  2  2
sizeof(float)  4  4
sizeof(int)  4  4
sizeof(unsigned int)  4  4
sizeof(long)  4  8
sizeof(double)  8  8
sizeof(long unsigned int)  4  8
sizeof(long double) 12 16
sizeof(long int)  4  8

x64

Linux 3.0.0-16-generic #28-Ubuntu SMP Fri Jan 27 17:44:39 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

x32

Linux 2.6.18-6-k7 #1 SMP Thu Aug 20 22:36:26 UTC 2009 i686 GNU/Linux

Si consiglia di utilizzare:

sys/types.h

dove vengono dichiarati i tipi:

int8_t
u_int8_t
int16_t
u_int16_t
int32_t
u_int32_t
int64_t
u_int64_t

Threads pool (posix) – c language (ver 2)

Example of generalized thread pool in C language with signal handling.

rev 2: Completely revised the code of the library.
Now there is a queue of jobs, a thread is awakened when a new job is available, following the classic mechanism of producer / consumer.

You can set: the thread pool size, its signal mask and the size of the job queue, calling the poolInit function that returns a new pool. If the signal mask is null then the signal mask shall be inherited from the creating thread.

The function poolDispatcher gets three arguments the pointer to the pool; a void pointer to function (start_routine), with a single argument void arg. (very similar to pthread_create). The poolDispather when executed creates a new job that is inserted into the queue of jobs.

If you send too many jobs to the pool and the queue fills up, the poolDispatcher reject the new job and returns the error code “-5” (to avoid DOS attacks).
The function poolDestroy, puts the pool in termination state, (the pool is no longer available to run new job), it waits for all active and pending jobs to finish; execute the join of the threads; free resources and exit.
doxygen docomuntation and source code (license GPLv2)

 

Esempio di pool di thread in linguaggio C generalizzato con gestione dei segnali.

E’ possibile passare a questa libreria un proprio puntatore a funzione.
La funzione verrà eseguita dal primo thread disponibile del pool di threads.

E’ facile notare come la funzione addjob esegue, nel caso in cui tutti i threads siano impegnati, attesa attiva.
La soluzione è presto detta, implementare una lista di jobs, oppure (per chi non ha voglia) aumentare opportunamente la dimensione del pool threads.

[update]
Rivisto completamente il codice della libreria.
Adesso esiste una lista di job; un thread del pool viene risvegliato quando un nuovo job è disponibile, seguendo il classico meccanismo di produttore/consumatore.

La dimensione massima della coda dei job è settabile in fase di creazione del pool.
Se si inviano troppi job al pool e la coda si riempie, la poolDispatcher rifiuterà il nuovo job ritornando il codice di errore “-5” (evitiamo attacchi di DOS).

La funzione poolDestroy, mette il pool in fase di terminazione, (ovvero il pool non è più disponibile ad eseguire nuovi job), aspetta che tutti i job attivi e pendenti terminino; esegue la join dei threads; libera le risorse ed esce.
[update-end]

Una volta terminato il job, il thread viene reso automaticamente disponibile per un nuovo job.
La dimensione del pool e la maschera dei segnali per i threads sono passate in fase di inizializzazione del pool stesso.

E’ possibile creare infiniti pool di threads, dato che ogni struttura dati viene creata dinamicamente in fase di inizializzazione del pool stesso. La maschera dei segnali è invece opzionale.

Per commenti e info più dettagliate sul codice: documentazione html (doxygen).

E per scaricare il codice sorgente: codice sorgente (in licenza gpl v2).