Yo'Sarin bloguje

Přeskočit navigaci

  • Všechny sekce
    (116 článků)
  • Fotogalerie
    (14 článků)
  • PC
    (15 článků)
  • Jen tak
    (58 článků)
  • Povídky
    (4 články)
  • O bloku
    (7 článků)
  • Škola
    (9 článků)
  • Hádanky
    (3 články)
  • Štafety
    (6 článků)
  • Přihlášení
  • Přepínač stylů

  • Semestrálka X36PKO - protokol TCP

    15. 4. 2008, 11:25 napsal Yo'Sarin, sekce Škola, přečteno 3381×, Linkuj si !

    Semestrálka na předmět X36PKO, přenos souborů po síti pomocí protokolu TCP. V článku je zadání + zdrojové kódy.

    Zadání

    1. Implementujte v jazyku C, C++ nebo Java nad rozhraním socketů TCP aplikaci umožňující přenos souborů pomocí protokolu TCP. Data zapisujte do kanálu opakovaně v menších blocích, než je velikost souboru (např. 128B).
    2. Serverovou část upravte tak, aby umožňovala obsluhovat více klientu najednou. Vybrat si můžete jednu ze dvou variant:

    Kódy:

    Server (tcps.h)

    #include <errno.h>

    #include <pthread.h>
    #include <stdio.h>
    #include <time..h>

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

    #define ECHOPORT 5566
    #define BUFFSIZE 512
    #define THREAD_COUNT 2

    struct data_t { int c_sockfd;
    int sockfd;
    struct data_t * prev;
    struct data_t * next;
    } ;

    struct threads_t { pthread_t * thread;
    struct threads_t * next;
    } ;

    // mutex zamykajici pohromade soubory
    pthread_mutex_t out;
    pthread_mutex_t checkConnection;
    pthread_cond_t condition = PTHREAD_COND_INITIALIZER;

    int freeThreads;

    void * writeData(void * data);

    // data socketů připravených na zpracování
    struct data_t * pendingSockets;
    struct data_t * headPointer;

    struct threads_t * threadsList;
    struct threads_t * threadsListHead;

    int main(int argc, char *argv[])
    { system("clear");
    pendingSockets = malloc(sizeof(struct data_t));
    pendingSockets->next = NULL;
    pendingSockets->prev = NULL;
    headPointer = pendingSockets;
    struct sockaddr_in my_addr, rem_addr;
    int rem_addr_length;

    int sockfd;

    if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
    { perror("Socket nelze otevrit");
    exit(1);
    }

    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(ECHOPORT);

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
    { perror("Chyba v bind");
    close(sockfd); exit(1);
    }

    if (listen(sockfd, 5) == -1)
    { perror("Nelze provest listen");
    close(sockfd); exit(1);
    }

    int run = 0;
    printf("-----------------------\n");
    threadsList = malloc(sizeof(struct threads_t));
    threadsList->next = NULL;
    threadsListHead = threadsList;
    int k;
    for (k = 0; k < THREAD_COUNT; k++) { freeThreads++;
    threadsList->next = malloc(sizeof(struct threads_t));
    pthread_create(threadsList->thread, NULL, writeData, NULL);
    threadsList = threadsList->next;
    threadsList->next = NULL;
    }
    while (1)
    { int c_sockfd;

    //printf("Prubeh %i\n", run++);
    rem_addr_length=sizeof(rem_addr);
    if ((c_sockfd = accept(sockfd, (struct sockaddr *)&rem_addr, &rem_addr_length)) == -1)
    { perror("Nelze prijmout spojeni.");
    close(sockfd);
    exit(1);
    }
    if(freeThreads == 0) { freeThreads++;
    threadsList->next = malloc(sizeof(struct threads_t));
    pthread_create(threadsList->thread, NULL, writeData, NULL);
    threadsList = threadsList->next;
    threadsList->next = NULL;
    }
    pthread_mutex_lock(&checkConnection);
    pendingSockets->next = malloc(sizeof(struct data_t));
    pendingSockets->next->next = NULL;
    pendingSockets->next->c_sockfd = c_sockfd;
    pendingSockets->next->sockfd = sockfd;
    pendingSockets->next->prev = pendingSockets;
    pendingSockets = pendingSockets->next;
    pthread_mutex_unlock(&checkConnection);
    pthread_cond_signal(&condition);
    }
    close(sockfd);
    }

    void * writeData(void * data)
    { while (1) { freeThreads--;
    // vlákno poběží immerwere
    //int assigned = -1;
    int sockfd, c_sockfd;
    //while (assigned == -1) {
    //sleep(1);
    pthread_cond_wait(&condition, &checkConnection);
    pthread_mutex_lock(&checkConnection);
    if (headPointer->next != NULL) { headPointer = headPointer->next;
    sockfd = headPointer->sockfd;
    c_sockfd = headPointer->c_sockfd;
    free(headPointer->prev);
    headPointer->prev = NULL;
    //assigned = 1;
    }
    pthread_mutex_unlock(&checkConnection);
    //}

    char filename[255];
    filename[0] = 'r';
    filename[1] = 'e';
    filename[2] = 'c';
    filename[3] = 'i';
    filename[4] = 'e';
    filename[5] = 'v';
    filename[6] = 'e';
    filename[7] = 'd';
    filename[8] = '/';
    filename[9] = '\0';
    int place = strlen(filename);

    int state;

    int mlen;

    char buf[BUFFSIZE];
    while ((state = (mlen = recv(c_sockfd, buf, 1, 0))) && *buf != '\n' && state != -1) { filename[place++] = buf[0];
    filename[place] = '\0';
    }
    if (state == -1) { pthread_mutex_lock(&out);
    perror("Nelze prijmout nazev souboru");
    close(c_sockfd);
    pthread_mutex_unlock(&out);
    return 1;
    }
    int size = 0;
    int count = 0;
    while ((state = (mlen = recv(c_sockfd, buf, 1, 0))) && *buf != '\n' && state != -1) { if (buf[0] - (int)'0' > 9 || buf[0] - (int)'0' < 0) continue;
    size = size * 10 + buf[0] - (int)'0';
    }
    if (state == -1) { pthread_mutex_lock(&out);
    perror("Nelze prijmout velikost souboru");
    close(c_sockfd);
    pthread_mutex_unlock(&out);
    return 1;
    } else { pthread_mutex_lock(&out);
    fopen(filename, "wb");
    printf("Klient: %i\n", c_sockfd);
    printf("Soubor: %s\n", filename);
    printf("Velikost: %ib\n", size);
    printf("-----------------------\n");
    pthread_mutex_unlock(&out);
    FILE * file = fopen(filename, "wb");
    if (file == NULL) { pthread_mutex_lock(&out);
    printf("Nepodarilo se vytvorit soubor %s.\n", filename);
    close(c_sockfd);
    pthread_mutex_unlock(&out);
    return 1;
    }
    count = 0;
    if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1) { pthread_mutex_lock(&out);
    perror("Chyba pri cteni");
    fclose(file);
    close(c_sockfd);
    pthread_mutex_unlock(&out);
    return 1;
    } else while (mlen) { pthread_mutex_lock(&out);
    count += mlen;
    int res = fwrite(buf, 1, mlen, file);
    if(res != mlen) { perror("Nepodarilo se ulozit data do souboru");
    fclose(file);
    close(c_sockfd);
    pthread_mutex_unlock(&out);
    return 1;
    } else if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1) { perror("Chyba pri cteni");
    fclose(file);
    close(c_sockfd);
    pthread_mutex_unlock(&out);
    return 1;
    }
    pthread_mutex_unlock(&out);
    }
    pthread_mutex_lock(&out);
    printf("Klient: %i\n", c_sockfd);
    printf("Soubor: %s\n", filename);
    printf("Prenos dokoncen\n");
    printf("-----------------------\n");
    pthread_mutex_unlock(&out);
    fclose(file);
    close(c_sockfd);
    }
    freeThreads++;
    }
    }

    Klient (tcp.h)

    #include

    #include
    #include
    #include

    #define ECHOPORT 5566
    #define BUFFSIZE 2048

    main(int argc, char *argv[])
    { char buf[BUFFSIZE];
    int s, len, off;
    struct sockaddr_in sin;

    if (argc < 2)
    { printf("pouziti: %s ip_cislo_serveru\n", argv[0]);
    exit(1);
    }

    if ((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1)
    { perror("nelze vytvorit socket");
    exit(1);
    }

    bzero(&sin, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(ECHOPORT);
    sin.sin_addr.s_addr = inet_addr(argv[1]);
    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
    { perror("nelze connect");
    close(s);
    exit(1);
    }

    if (write(s, buf, BUFFSIZE) != BUFFSIZE)
    { perror("chyba pri zapisu");
    close(s);
    exit(1);
    }

    off=0;
    do
    { if((len=read(s, buf+off, BUFFSIZE-off))<=0)
    { perror("chyba pri cteni");
    close(s);
    exit(1);
    }
    printf("len: %i\n", len);
    off+=len;
    }
    while (off!=BUFFSIZE);

    printf("%d bytu bylo opakovano serverem\n", off);
    close(s);

    return 0;
    }

    Diskuze k článku:

    Diskusní příspěvky vyjadřují názory diskutujících, nikoli autora článku.
    Příspěvky nemající souvislost s článkem a příspěvky jejichž jediným účelem je urážet a nadávat budou po zralé úvaze smazány - uvědomte si, že jste na mém písečku.

    #1: TiGR, přidáno: 15. 4. 2008, 15:49

    Avatar uživatele TiGRTaky jsi to mohl napsat v jave, kdo se ma v tomhle orientovat :-<


    #2: Yo'Sarin, přidáno: 17. 4. 2008, 09:44, web: http://www.yosarin.net

    Avatar uživatele Yo'SarinTos uhodl, já se kvůli jedné semestrálce budu znova šťourat v Javě... :-) Bohatě mi stačí že se sem tam musim šťourat v JavaScriptu. ;-)


    Přidat nový příspěvek




    Yo'Sarinkovy stránky Blog o všem, co jste už četli jinde Jediný blog se zápornou návštěvností No-more-Didinka I admini mají své dny
    Yo'Sarinkův blok I RSS tu mám Pagerank? Co s ním.
    http://blok.yosarin.net/sekce-8~Skola/clanek-92~Semestralka-X36PKO-protokol-TCP