Raccolta di howto, informazioni, consigli, trucchi e documentazione di varia utilità per ricordare tante cose utili

giovedì 4 febbraio 2010

Realizzazione di un TCP server multithread in linguaggio C, C++

La parte iniziale del programma deve contenere gli include necessari per l'uso dei socket:
#include
#include
#include
#include

int main(int argc, char *argv[])
{
    int sockfd;
    int newsockfd = 0;
    struct sockaddr_in serv_addr, cli_addr;
si crea il socket per il server
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if ( sockfd < 0 ) {
        perror("FATAL: Impossibile aprire il listener TCP");
        exit(1);
    }
si esegue il bind sull'indirizzo/porta voluto
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(0x4bfc);
    if ( bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) {
        perror("FATAL: Impossibile effettuare il bind del listener TCP");
        exit(1);
    }
e lo si pone in ascolto 
    listen(sockfd,5);
a questo punto per ogni nuova connessione entrante accettata si crea uno thread specifico che la gestisce. E' necessario attendere di essere sicuri che il nuovo thread abbia preso in carico il valore del socket da usare per la comunicazione.
    while( true ) {
        socklen_t clilen = sizeof(cli_addr);
        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
        if ( newsockfd < 0 ) {
            perror("Nuova connessione non creata");
        } else {
            pthread_t pTh;
            pthread_create(&pTh, NULL, InitiateThreadTCP, (void *)newsockfd);
            pthread_detach(pTh);
            int maxsleep = 1000;
            while (newsockfd > 0 && maxsleep > 0) {
                usleep(1000);
                maxsleep--;
            }
        }
    }
la funzione di gestine della comunicazione è la seguente, bisogna ricordarsi di definirla all'inizio del file prima del main.
void * InitiateThreadTCP( void *p )
{
    int sck = &(int *)p;
    char rbuffer[1000];
    char sbuffer[1128];
 
    int n = read(sck, rbuffer, 1022);
    if (n >= 0) {
        rbuffer[n] = 0;
        sprintf(sbuffer, "Ricevuto messaggio: %s ", rbuffer);
        write(sck, sbuffer, strlen(sbuffer));
    }
    close(sck);
    pthread_exit( NULL );
}
Di seguito il sorgente completo
#include
#include
#include
#include

void * InitiateThreadTCP( void *p )
{
    int sck = &(int *)p;
    char rbuffer[1000];
    char sbuffer[1128];
 
    int n = read(sck, rbuffer, 1022);
    if (n >= 0) {
        rbuffer[n] = 0;
        sprintf(sbuffer, "Ricevuto messaggio: %s ", rbuffer);
        write(sck, sbuffer, strlen(sbuffer));
    }
    close(sck);
    pthread_exit( NULL );
}

int main(int argc, char *argv[])
{
    int sockfd;
    int newsockfd = 0;
    struct sockaddr_in serv_addr, cli_addr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if ( sockfd < 0 ) {
        perror("FATAL: Impossibile aprire il listener TCP");
        exit(1);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(0x4bfc);
    if ( bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) {
        perror("FATAL: Impossibile effettuare il bind del listener TCP");
        exit(1);
    }
 
    listen(sockfd,5);

    while( true ) {
        socklen_t clilen = sizeof(cli_addr);
        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
        if ( newsockfd < 0 ) {
            perror("Nuova connessione non creata");
        } else {
            pthread_t pTh;
            pthread_create(&pTh, NULL, InitiateThreadTCP, (void *)newsockfd);
            pthread_detach(pTh);
            int maxsleep = 1000;
            while (newsockfd > 0 && maxsleep > 0) {
                usleep(1000);
                maxsleep--;
            }
        }
    }

    exit(0);
}

2 commenti:

Anonimo ha detto...

Una domanda....le librerie da includere quali sono??

Ciao

Unknown ha detto...

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


su per giù sono queste :)