Здравствуйте! У меня есть проект «Система обмена файлами».
Задание: разработать приложение-клиент и приложение сервер, обеспечивающие функции обмена файлами.
Клиент может:
- Получить список файлов хранящихся на сервере.
- Добавить файл.
- Удалить файл.
- Скачать файл.
- Отключиться от сервера.
- Отключить сервер и сам отключиться.
Сервер:
- Обновляет и отправляет список файлов клиенту.
- Получает файл в папку files сервера.
- Получает номер файла для удаления из папки files.
- Отправляет файл клиенту
- Пишем сообщение,что клиент отключился.
- Завершаем работу сервера
Листинг Сервер:
/*  HELP:
..Server:
.........path: /home/bladzher/projects/[CLion]/FileTransferSystem/trunk/server
.........gcc server.c -o server
..Client
.........path: /home/bladzher/projects/[CLion]/FileTransferSystem/trunk/client
.........gcc client.c -o client
*******************************************************************************
*
* PATH files:
* ...........PC name: /ksergey/
* ...........Ultrabook name: /bladzher/
*
*******************************************************************************
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
#include "dirent.h"
#define BUF_SIZE 1024
#define TEXT "Вы успешно подключились к системе передачи файлов!\n\nМЕНЮ:\n1)Отобразить список файлов.\n2)Добавить файл.\n3)Удалить файл.\n4)Скачать файл.\n5)Выход.\n6)Выключить сервер.\n"
char message1[1];
char buf1[sizeof(message1)];
int main() {
    int sock, listener;      // дескрипторы сокетов
    struct sockaddr_in addr; // структура с адресом
    char buf;          // буфер для приема
    int bytes_read;              // кол-во принятых байт
    listener = socket(AF_INET, SOCK_STREAM, 0); // создаем сокет для входных подключений
    if (listener < 0) {
        perror("socket");
        exit(1);
    }
    // Указываем параметры сервера
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3425);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(listener, (struct sockaddr *) &addr, sizeof(addr)) < 0) // связываемся с сетевым устройство. Сейчас это устройство lo - "петля", которое используется для отладки сетевых приложений
    {
        perror("bind");
        exit(2);
    }
    listen(listener, 1); // очередь входных подключений
    int number, *ptn;
    number = 0;
    ptn = &number;
    int number1, *ptn1;
    number1 = 0;
    ptn1 = &number1;
    printf("\nОжидание подключения:\n");
    while (1) {
        sock = accept(listener, NULL, NULL); // принимаем входные подключение и создаем отделный сокет для каждого нового подключившегося клиента
        if (sock < 0) {
            perror("accept");
            exit(3);
        }
        char text[] = TEXT;
        send(sock, text, sizeof(text), 0);
        printf("К серверу подключился клиент!Ожидаем команду:\n");
        recv(sock, (void *) &number, 4, 0);
        printf("Получена команда от клиента: %d\n", *ptn);
        send(sock, "Сервер получил сообщение!", sizeof("Сервер получил сообщение!"), 0);
/*        ///Информация о файле
//        char *date;
//        int ret;
//        struct stat buf1;
//        if((ret = stat("/home/bladzher/projects/[CLion]/FileTransferSystem/trunk/server/files/Дима_Пряхин-новая_религия.mp3", &buf1)) !=0)
//        {
//            fprintf(stderr, "stat failure error .%d", ret);
//            abort();
//        }
//        date = asctime(localtime((time_t const *) &buf1.st_ctim));
//        printf("\n %s\n", date);
//        printf("\n %d mode\n", buf1.st_mode);
//        printf("\n %ld size\n", buf1.st_size);
        //Конец_Информация о файле*/
        if (*ptn == 1) {
            DIR *dir;
            struct dirent *entry;
            dir = opendir("/home/bladzher/projects/[CLion]/FileTransferSystem/trunk/server/files");
            if (!dir) {
                perror("diropen");
                close(sock);
                exit(4);
            }
            FILE *fo;
            if (!(fo = fopen("/home/bladzher/projects/[CLion]/FileTransferSystem/trunk/server/list.xml", "wt"))) {
                perror("fopen");
                close(sock);
                exit(6);
            }
            int i = 0;
            while ((entry = readdir(dir)) != NULL) {
                fprintf(fo, "%d)%s\n", i, entry->d_name);
                printf("%d)%s\n", i, entry->d_name);
                i++;
            }
            send(sock, entry, sizeof(entry), 0);
            closedir(dir);
            fclose(fo);
            FILE *f;
            if (!(f = fopen("/home/bladzher/projects/[CLion]/FileTransferSystem/trunk/server/list.xml", "rb"))) {
                perror("fopen");
                close(sock);
                exit(7);
            }
            fseek(f, 0, SEEK_END);
            int fsize = (int) ftell(f);
            rewind(f);
            long sended = 0;
            long readed = 0;
            char buffer[BUF_SIZE];
            do {
                readed = fread(buffer, 1, BUF_SIZE, f);
                send(sock, buffer, (size_t) readed, 0);
                sended += readed;
            } while (sended != fsize);
            fclose(f);
        }
        else if (*ptn == 2) {
            //Получаем имя и расширение файла
            //Получаем файл и добавляем его в папку files сервера.
            //Пишем клиенту,что файл успешно добавлен или иное.
        }
        else if (*ptn == 3) {
            recv(sock, (void *) &number1, 4, 0);
            printf("Получен номер файла для удаления: %d\n", *ptn1);
            //определяем имя и расширение файла
            //удаляет данный файл
            send(sock, "Сервер удалил файл!", sizeof("Сервер удалил файл!"), 0);
        }
        else if (*ptn == 4) {                                     //Передача файла
            FILE *f;
            if (!(f = fopen("/home/bladzher/projects/[CLion]/FileTransferSystem/trunk/server/files/Дима_Пряхин-новая_религия.mp3", "rb"))) {
                perror("fopen");
                close(sock);
                exit(8);
            }
            fseek(f, 0, SEEK_END);
            int fsize1 = (int) ftell(f);
            rewind(f);
            long sended1 = 0;
            long readed1 = 0;
            char buffer[BUF_SIZE];
            do {
                readed1 = fread(buffer, 1, BUF_SIZE, f);
                send(sock, buffer, (size_t) readed1, 0);
                sended1 += readed1;
            } while (sended1 != fsize1);
            fclose(f);
        }                                                   ///Конец_Передача файла
        else if (*ptn == 5) {
            printf("Клиент отключился!\n");
        }
        else if (*ptn == 6) {
            break;
        }
        close(sock); // закрываем сокет
        printf("\nОжидание подключения:\n");
    }
    close(sock);
    return 0;
}
Листинг Клиент:
/*  HELP:
..Server:
.........path: /home/bladzher/projects/[CLion]/FileTransferSystem/trunk/server
.........gcc server.c -o server
..Client
.........path: /home/bladzher/projects/[CLion]/FileTransferSystem/trunk/client
.........gcc client.c -o client
*******************************************************************************
*
* PATH files:
* ...........PC name: /ksergey/
* ...........Ultrabook name: /bladzher/
*
*******************************************************************************
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
//#include <dialog.h>
#include <time.h>
#include <search.h>
#include <bits/string2.h>
#define BUF_SIZE 1024
char message[1024];
char buf[sizeof(message)];
int main() {
    int sock;                // дескриптор сокета
    struct sockaddr_in addr; // структура с адресом
    sock = socket(AF_INET, SOCK_STREAM, 0); // создание TCP-сокета
    if (sock < 0) {
        perror("socket");
        exit(1);
    }
    // Указываем параметры сервера
    addr.sin_family = AF_INET; // домены Internet
    addr.sin_port = htons(3425); // Порт
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) // установка соединения с сервером
    {
        perror("Подключение");
        exit(2);
    }
    int number, *ptn;
    number = 0;
    ptn = &number;
    int number1, *ptn1;
    number1 = 0;
    ptn1 = &number1;
    recv(sock, message, sizeof(message), 0);
    printf("Сообщение от сервера: %s\n", message);
    printf("Введите команду серверу:");
    scanf("%d", &number);
    printf("Отправляю сообщение клиенту.\n");
    send(sock, (void const *) &number, 4, 0); // отправка сообщения на сервер
    recv(sock, message, sizeof(message), 0);
    printf("%d\n", *ptn);
    long buffer[BUF_SIZE];
    long rcv_len = 0;
    if (*ptn == 1) {
        FILE *f;
        if (!(f = fopen("/home/bladzher/Загрузки/list.xml", "wb"))) {
            perror("fopen");
            close(sock);
            exit(3);
        }
        do {
            rcv_len = recv(sock, buffer, BUF_SIZE, 0);
            fwrite(buffer, 1, (size_t) rcv_len, f);
        } while (rcv_len != 0);
        fclose(f);
    } else if (*ptn == 2) {
        char str[128];
        char str1[128];
        char str2[257];
        printf("Введите полный путь до файла[/home/bladzher/projects/[CLion]/FileTransferSystem/trunk/client/files/]:");
        scanf("%s", (char *) &str);
        printf("Ввелите полное имя файла с расширением[Сплин - Выхода нет.mp3]:");
        scanf("%s", (char *) &str1);
        //  printf("%s\n", str1);
        strcat(str2, str);
        strcat(str2, str1);
        printf("%s", str2);
        printf("\n");
    } else if (*ptn == 3) {
        printf("Введите номер файла для удаления:");
        scanf("%d", &number1);
        printf("Отправляю сообщение клиенту.\n");
        send(sock, (void const *) &number1, 4, 0); // отправка сообщения на сервер
        recv(sock, message, sizeof(message), 0);
        printf("%s\n", message);
    }
    else if (*ptn == 4) {                                              //Прием файла
        FILE *f;
        if (!(f = fopen("/home/bladzher/Загрузки/Дима_Пряхин-новая_религия.mp3", "wb"))) {
            perror("fopen");
            close(sock);
            exit(4);
        }
        rcv_len = 0;
        do {
            rcv_len = recv(sock, buffer, BUF_SIZE, 0);
            fwrite(buffer, 1, (size_t) rcv_len, f);
        } while (rcv_len != 0);
        fclose(f);
    }
        //Конец_Прием файла
    else if (*ptn == 5) {
        close(sock);
    }
    else if (*ptn == 6) {
        close(sock);
    }
    close(sock); // закрываем сокет
    return 0;
}
Подскажите пожалуйста в чем проблема,у меня при выборе первого варианта файл list.xml 0 байт у клиента,а тот же код только отправляю песню (4 вариант) все отправляется.
+ подскажите пожалуйста по коду,как лучше сделать данный проект,какие-нибудь советы.
+ проблема в том,что когда я выключаю сервер (Ctrl + C) или когда клиент посылает команду под номером 6(Откл.сервера),то при повторном запуске сервера пишется "./server bind: Address already in use" - как это исправить?
P.S. Извините,если плохо,что описал,спешу на работу,а спросить необходимо.Если будут вопросы пишите!
+ Теги почему-то не работают,чтобы красиво оформить :(




