Здравствуйте! У меня есть проект «Система обмена файлами».
Задание: разработать приложение-клиент и приложение сервер, обеспечивающие функции обмена файлами.
Клиент может:
- Получить список файлов хранящихся на сервере.
- Добавить файл.
- Удалить файл.
- Скачать файл.
- Отключиться от сервера.
- Отключить сервер и сам отключиться.
Сервер:
- Обновляет и отправляет список файлов клиенту.
- Получает файл в папку 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. Извините,если плохо,что описал,спешу на работу,а спросить необходимо.Если будут вопросы пишите!
+ Теги почему-то не работают,чтобы красиво оформить :(