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

Visualizzazione post con etichetta rete. Mostra tutti i post
Visualizzazione post con etichetta rete. Mostra tutti i post

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);
}

martedì 26 gennaio 2010

Utilizzo del comando "ssmtp" con Gmail

Quando su un sistema linux non abbiamo necessità di ricevere mail possiamo evitare le difficolta ed il lavoro ceh comporta l'installazione di un smtp server quale ad esempio sendmail, ricorrendo per l'invio al comando ssmtp.
Come primo passo è necessario installare il programma: su un sistema ubuntu utilizziamo il comando
sudo apt-get install ssmtp
se invece si utilizza un sistema gentoo si deve date il comando
emerge mail-mta/ssmtp

La configurazione si trova nel file /etc/ssmtp/ssmtp.conf ed è sostanzialmente composta da 5 linee:
root=mioindirizzo@gmail.com
mailhub=smtp.gmail.com:587
AuthUser=miogmailusername
AuthPass=miogmailpassword
UseSTARTTLS=YES

Si deve ora creare il file con il contenuto della mail. Il file deve contenere tre linee di intestazione con i campi To, From e Subject, seguiti da una linea vuota e dal testo del messaggio. Di seguito un esempio
To: destinatario@tin.it
From mioindirizzo@gmail.com
Subject: Oggetto del messaggio

Qui dopo una linea vuota inserisco il testo del messaggio

A questo punto si può inviare la mail dando il comando:
ssmtp destinatario@tin.it < msg.txt

giovedì 10 dicembre 2009

Ricezione di pacchetti UDP in C

Di seguito la procedura per ricevere un pacchetto UDP attraverso un socket in un sorgente C per linux/unix.
Iniziamo definendo gli opportuni include generici:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
gli include specifici per il funzionamento dei socket
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
e le definizione dell'indirizzo ip e della porta sulla quale porci in ascolto
#define PORT (5000)
Successivamente creiamo il socket UDP
int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
  perror("Creazione socket fallita");
  exit(1);
}
definiamo e valorizziamo la struttura contenente le informazioni sulla porta sul quale effettuare il bind del socket
struct sockaddr_in addr_loc;
memset((char *)&addr, sizeof(addr), 0);
addr_loc.sin_family = AF_INET;
addr_loc.sin_port = htons(PORT);
addr_loc.sin_addr.s_addr = htonl(INADDR_ANY);
bind(s, (sockaddr *)&addr_loc, sizeof(addr_loc));
per porci in ascolto dobbiamo prima creare una struttura nella quale la funzione recvfrom ci restituisca l'indirizzo dal quale proviene il pacchetto
struct sockaddr_in addr_rem;
socklen_t slen = sizeof(addr_rem);
char buf[1500];
int r = recvfrom(s, buf, 1500, 0, (sockaddr *)&addr_rem, &slen);  
ed infine possiamo leggere il contenuto del pacchetto e il suo indirizzo di provenienza
printf("Received packet from %s:%d\nData: %s\n\n", inet_ntoa(addr_rem.sin_addr), ntohs(addr_rem.sin_port), buf);
Per concludere chiudiamo il socket
close(s);
Da notare che l'indirizzo ip della sorgente viene conservato nella variabile  addr_rem.sin_addr.s_addr in forma di intero a 32 bit (4 byte) dove il byte meno significativo è il primo dell'indirizzo ip nella forma numerica standard
dcba (4 byte) = a.b.c.d

mercoledì 9 dicembre 2009

Invio di pacchetti UDP in C (unix)

Di seguito la procedura per inviare un pacchetto UDP attraverso un socket in un sorgente C per linux/unix.
Iniziamo definendo gli opportuni include generici:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
gli include specifici per il funzionamento dei socket
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
e le definizione dell'indirizzo ip e della porta di destinazione
#define IPADDR "192.168.1.100"
#define PORT (5000)
Successivamente creiamo il socket UDP
int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
  perror("Creazione socket fallita");
  exit(1);
}
definiamo e valorizziamo la struttura contenente la destinazione del pacchetto
struct sockaddr_in addr;
memset((char *)&addr, sizeof(addr), 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
inet_aton(IPADDR, &addr.sin_addr);
Creiamo e valorizziamo il buffer con i dati da inviare
int buf[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ed infine inviamo il pacchetto sulla rete alla destinazione voluta
int len=sendto(s, buf, 10*sizeof(int), 0, (struct sockaddr *)&addr, sizeof(addr));
if(len < (10*sizeof(int))) perror("Invio fallito o incompleto");
Per concludere chiudiamo il socket
close(s);
Di seguito il sorgente completo

#include <stdlib.h>
#include <stdio.h>;
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define IPADDR "192.168.1.100"
#define PORT (5000)

int main() {

  int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (s == -1) {
    perror("Creazione socket fallita");
    exit(1);

  }

  struct sockaddr_in addr;
  memset((char *)&addr, sizeof(addr), 0);

  addr.sin_family = AF_INET;
  addr.sin_port = htons(PORT);
  inet_aton(IPADDR, &addr.sin_addr);


  int buf[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

  int len=sendto(s, buf, 10*sizeof(int), 0, (struct sockaddr *)&addr, sizeof(addr));
  if(len < (10*sizeof(int))) perror("Invio fallito o incompleto");

  close(s);

  return 0;
}