All pastes #502646 Raw Edit

Mine

public c v1 · immutable
·published 2007-05-22 15:58 UTC
rendered paste body
#include <stdio.h>      /* for printf() and fprintf() */#include <sys/socket.h> /* for socket(), bind(), and connect() */#include <arpa/inet.h>  /* for sockaddr_in and inet_ntoa() */#include <stdlib.h>     /* for atoi() and exit() */#include <string.h>     /* for memset() */#include <unistd.h>     /* for close() */#include <pthread.h>#include <sys/select.h>#include <sys/time.h>#include <sys/types.h>#include <signal.h>#include "server.h"#define MAXPENDING 5    /* Maximum outstanding connection requests */#define MAX_THREADS 2   /*anzahl maximaler Nutzer */#define Z_VERBUNDEN 1#define Z_HELO      2#define Z_MAIL      3#define Z_RECEIPT   4#define Z_DATA      5#define Z_QUIT      6#define BEF_ANZ     6int servSock;                     /* Socket descriptor fur server */char join_thread[MAX_THREADS];    //feld aktiver threadspthread_t threads[MAX_THREADS];   //fehlt abgearbetieter threadspthread_mutex_t mx_join;          //semeaphore für exkl. zugriffstruct zustaende{    int zustand;    char *kommando;};struct zustaende befehle[]={    {Z_VERBUNDEN, " "},    {Z_HELO, "HELO "},    {Z_MAIL, "MAIL FROM: "},    {Z_RECEIPT, "RCPT TO: "},    {Z_DATA, "DATA "},    {Z_QUIT, "QUIT "}};int daten_lesen(int fd, char* buf, int max_len){    struct timeval tv;    fd_set fds;    int ret, len;    FD_ZERO(&fds);    FD_SET(fd, &fds);    tv.tv_sec = 10;    tv.tv_usec = 0;    //hier kommt select und createthread hin    ret = select(fd + 1, &fds, NULL, NULL, &tv);    if(ret == 0) return 0;    if(ret < 0)    {        perror("select");        return -1;    }    memset(buf, 0, max_len);            //bufffer wird mit 0 initialisiert    len = read(fd, buf, max_len);    if(len <=0)return 0;    buf[ max_len -1 ]='\0';    return len;}int verbindungsabbau(int sock){    int id = pthread_self();    int i, ret=0;    close(sock);    printf("beenden!\n");    /* locked */    pthread_mutex_lock( &mx_join );    for(i=0; i<MAX_THREADS; i++)    {        if(threads[i] == id)            break;    }    if(i == MAX_THREADS)    {        printf("ganz schlecht!\n");        exit(1);    }    join_thread[i] = 1;    pthread_mutex_unlock( &mx_join );    /* unlocked */    pthread_exit(&ret);    return 0;}int prufen(char* eing, int len){    int i=0, bef_len;    for(i=0; i<BEF_ANZ; i++)    {        bef_len = strlen(befehle[i].kommando);        if(len < bef_len) continue;        if(strncasecmp(eing, befehle[i].kommando, bef_len) == 0)        {            switch (befehle[i].zustand)             {            case Z_HELO:                printf("servus \n");                break;            case Z_MAIL:                break;            case Z_RECEIPT:                break;            case Z_DATA:                break;            case Z_QUIT:                break;            default:                break;            }            break;        }    }    return 0;}/*fangt das Signal Strg+C ab und beendet alles Verbindugen korrekt*/void sighandler(int sig){    if(sig == SIGINT)    {        printf("caught SIGINT!\n");        close(servSock);        exit(1);    }}int main(int argc, char *argv[]){    int clntSock;                    /* Socket descriptor for server */    struct sockaddr_in smtpServAddr; /* Local address */    struct sockaddr_in smtpClntAddr; /* Client address */    unsigned short smtpServPort;     /* Server port */    fd_set fds;    struct timeval tv;    int ret, i;    unsigned int clntLen;    void *value;    signal(SIGINT, sighandler);       //sighandler initialisierung      pthread_mutex_init( &mx_join, NULL ); //semaphore initialisierung    memset(join_thread, 0, sizeof(join_thread));  //initialisierung der thread tabelle    if (argc != 2)     /* test ob anzahl der argumente korrekt ist */    {        fprintf(stderr, "Usage:  %s <Server Port>\n", argv[0]);        return -1;    }    smtpServPort = atoi(argv[1]);  /* erstes argument:  server port */    /* Socket fur eingehende Verbindungen starten */    if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)    {        perror("socket");        return -1;    }    /* Construct local address structure */    memset(&smtpServAddr, 0, sizeof(smtpServAddr));   /* Zero out structure */    smtpServAddr.sin_family = AF_INET;                /* Internet address family */    smtpServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */    smtpServAddr.sin_port = htons(smtpServPort);      /* Local port */    /* Bind an lokale adresse */    if (bind(servSock, (struct sockaddr *) &smtpServAddr, sizeof(smtpServAddr)) < 0)    {        perror("bind() failed");        return -1;    }    /* socket wird zyklisch abgehort */    if (listen(servSock, MAXPENDING) < 0)    {        perror("listen() failed");        return -1;    }    for (;;) /* endloses warten auf Clienten */    {        /* locked */        pthread_mutex_lock( &mx_join );        for(i=0; i<MAX_THREADS; i++) //maximal MAX_THREADS clienten können sich verbinden, danach warten die weiteren in einer warteschlange        {            if(join_thread[i] == 1)            {                pthread_join(threads[i], &value);                threads[i] = 0;                join_thread[i] = 0;            }        }        pthread_mutex_unlock( &mx_join );        /* unlocked */        FD_ZERO(&fds);        FD_SET(servSock, &fds);        tv.tv_sec = 0;              //zeit zyklus in sek        tv.tv_usec = 50000;         //in mikrosekunden        //hier kommt select und createthread hin        ret = select(servSock + 1, &fds, NULL, NULL, &tv); //wenn etwas auf den Serversocket ankommt        if(ret == 0) continue;                             // bei 0 mach weiter (beendeter Thread)        if(ret < 0) perror("select");                      // bei negativen Werten ist ein Fehler aufgetreten        for(i=0; i<MAX_THREADS; i++)                       // ist noch Platz für einen neuen Client ?            if(threads[i] == 0 ) break;        if(i == MAX_THREADS)                               // wenn nicht kurz warten        {            usleep(10000);            continue;        }         // erzeugen des ClientSockets zur direkten Verbindung        clntSock = accept(servSock, (struct sockaddr *) &smtpClntAddr, &clntLen);        if (clntSock < 0)            perror("accept() failed");        /* clntSock is connected to a client! */        printf("Handling client %s\n", inet_ntoa(smtpClntAddr.sin_addr));        ret = pthread_create(&threads[i], 0, (void*)handleClient, (void*) &clntSock); // jeder client bekommt einen Thread        if( ret != 0)            perror("pthread_create");    }    close(servSock); /* wird nie erreicht */}/* jeder Thread bekommt diese Funktion übergeben */void handleClient(void* arg){    int sock = *((int*) arg);    char buffer[1024];    int len=0, ret;    int i=0;    int zustand=0;    for (;;) /* endlos */    {        ret=daten_lesen(sock, buffer, 1024);        if(ret==0) continue;        if(ret<0) verbindungsabbau(sock);        prufen(buffer, ret);        if(strncmp(buffer, "quit", 4) == 0)           //beendung bei eingabe von quit        {            verbindungsabbau(sock);        }        printf("erhalten: %s", buffer);    }}