Russian Qt Forum
Май 21, 2024, 03:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: многопоточное копирование фала через сокет  (Прочитано 2923 раз)
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« : Октябрь 20, 2015, 20:40 »

Здравствуйте есть клиент сервер
смысл в том что при подключении клиента к серверу(запускается отдельный) начинается копирование файла на сторону клиента
вопрос в следующем возможно ли сделать так чтобы если запустить одновременно много клиентов(допустим 10) файл копировался параллельно на все клиенты.

Во вложении проекты

код сервера

Код
C++ (Qt)
#include <QCoreApplication>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <fcntl.h>
#include <pthread.h>
#include <QFile>
#include <QTime>
pthread_mutex_t s;
int i=0;
void* potokfunc(void* ps)  //начало потока функция
{
   int desk=*(int *)ps;
   char buf[100];  //отправка номера размера имени файла
   char buf2[2048]; //отправка данных файла
   pthread_mutex_lock(&s);
   i=i+1;
   pthread_mutex_unlock(&s);
 
 
   // ОТПРАВЛЯЕМ НОМЕР ПАПКИ
   sprintf(buf,"%d",i);
   printf("НОМЕР ПАПКИ=%s\n",buf);
   //sleep(1);
   int rez=send(desk,buf,strlen(buf),0);
   if (rez>0)
   {
       printf("номер папки отправлен \n");
   }
 
   memset(buf,0,sizeof(buf));  // очищаем буфер
 
   //ОТПРАВЛЯЕМ РАЗМЕР ФАЙЛА
   QFile a("/qqq");
   int razmer;
   razmer=rez=a.size();
   char *razmert=QString::number(rez).toLocal8Bit().data();
   //sleep(3);
   sprintf(buf,"%s",razmert);
   printf("РАЗМЕР ФАЙЛА=%s\n",buf);
   rez=send(desk,buf,strlen(buf),0);
   if (rez>0)
   {
       printf("размер файла отправлен\n");
 
   }
   memset(buf,0,sizeof(buf));  // очищаем буфер
   //ОТПРАВЛЯЕМ ИМЯ ФАЙЛА
   sprintf(buf,"%s","/qqq");
   printf("ИМЯ ФАЙЛА=%s\n",buf);
   //sleep(3);
   rez=send(desk,buf,strlen(buf),0);
   if (rez>0)
   {
       printf("имя файла отправлено \n");
 
   }
   //sleep(2);
   FILE *f=fopen(buf,"rb");
   if (f!=NULL)
   {
 
       while(!feof(f))
       {
           rez=fread(buf2,1,sizeof(buf2),f);
           if (rez>0)  // если данные в буфер передали
           {
               rez=send(desk,buf2,strlen(buf2),0);
               if (rez>0)
               {
                   razmer=razmer-rez;
               }
               if (razmer==0)  //весь файл считали
               {
 
                   break;
               }
           }
       }
   }
 
   return NULL;
 
 
 
}
 
int main(int argc, char *argv[])
{
   pthread_mutex_init(&s,0);
   int fd=socket(AF_INET,SOCK_STREAM,0);
   if (fd<0)
   {
       printf("ощибка создания сокета");
       return 0;
   }
   struct sockaddr_in sockad;
   struct sockaddr_in klient;
 
   sockad.sin_addr.s_addr=htonl(INADDR_ANY);
   sockad.sin_family=AF_INET;
   sockad.sin_port=htons(6643);
 
   int rez=bind(fd,(struct sockaddr *)&sockad,sizeof(sockad));
   if (rez<0)
   {
       printf("ошибка привязки");
       return 0;
   }
   rez=listen(fd,1000);
   if (rez<0)
   {
       printf("не готово принимать соединения\n");
       return 0;
   }
   printf("сервер запущен\n ЖДУ ПОДКЛЮЧЕНИЙ\n");
 
   while (1)
   {
       int len=sizeof(klient);
       int fda=accept(fd,(sockaddr *)&sockad,(socklen_t *) &len);
       if (fda>0)  //если произошло соединение
       {
           printf("произошло подключение создаю поток\n");
           pthread_t tid;  //создали объект потока
           int jj=pthread_create(&tid, NULL, &potokfunc, &fda);    //передаем связный файловый дескриптор
           if (jj!=0)
           {
               printf("поток не создан\n");
           }
           sched_yield();
       }
   }
 
 
 
 
   return 0;
}
 


код клиента

Код
C++ (Qt)
#include <QCoreApplication>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <fcntl.h>
#include <pthread.h>
#include <QFile>
#include <QTime>
#include <QDir>
#include <stdio.h>
 
using namespace std;
 
int main(int argc, char *argv[])
{
   char buf[100];
   char buf2[2048];
   memset(buf,0,sizeof(buf));
   memset(buf2,0,sizeof(buf2));
 
   int fd=socket(AF_INET,SOCK_STREAM,0);
   if (fd<0)
   {
       printf("ощибка создания сокета\n");
 
   }
 
   struct sockaddr_in sock;
   sock.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
   sock.sin_port=htons(6643);
   sock.sin_family=AF_INET;
 
   int rez=connect(fd,(sockaddr *)&sock,sizeof(sock));
   if (rez<0)
   {
       printf("ошибка коннекта\n");
       return 0;
   }
   //принимаем номер папки
   rez=recv(fd,buf,sizeof(buf),0);
   if (rez>0)
   {
       cout<<"НОМЕР ПАПКИ="<<buf<<endl;
       printf("номер папки получен\n");
   }
 
 
   QString papka="/1000ARM/"+QString(buf);
   cout<<papka.toStdString()<<endl;
   QDir a;
   a.mkdir("/1000ARM");
 
   if (a.mkdir(papka)==true)
   {
       printf("папка создана\n");
   }
 
   memset(buf,0,sizeof(buf));
   int razmer;
   //принимаем размер файла
   rez=recv(fd,buf,sizeof(buf),0);
   if (rez>0)
   {
       razmer=QString(buf).toInt();
       cout<<"РАЗМЕР ФАЙЛА="<<buf<<endl;
       printf("размер файла получен\n");
   }
 
   memset(buf,0,sizeof(buf));
 
   rez=recv(fd,buf,sizeof(buf),0);
   if (rez>0)
   {
       cout<<"ИМЯ ФАЙЛА="<<buf<<endl;
       printf("имя файла получено\n");
   }
 
   QString imyaf=papka+QString(buf);
   char *im=imyaf.toLocal8Bit().data();
   FILE *f=fopen(im,"wb");
   printf("\n");
   if (f!=NULL)
   {
       while(1)
       {
           memset(buf2,0,sizeof(buf2));
           rez=recv(fd,buf2,sizeof(buf2),0);
           if (rez>0)  //если мы получили данные
           {
               printf("данные получены=%s\n",buf2);
               rez=fwrite(buf2,1,rez,f); //данные записаны
               if (rez>0)  //если мы записали данные
               {
                    printf("получено байт=%d\n",rez);
                   razmer=razmer-rez;
               }
               if (razmer==0)
               {
                   printf("весь файл принят\n");
                   break;
               }
           }
       }
   }
 
 
 
 
   return 0;
}
 
 
 
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Октябрь 21, 2015, 13:26 »

Конечно, можно. Сервер должен подключать каждого клиента отдельно (например, в отдельном потоке) и отдавать ему файл.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
koldun90
Крякер
****
Offline Offline

Сообщений: 345


Просмотр профиля
« Ответ #2 : Октябрь 21, 2015, 21:21 »

стоп я как раз так и сделал...
у меня после того как клиент присоединился выполняется функция потока
а как можно читать один и тот же файл допустим 10 потоками.
он будет корректно читаться?
Записан
Bepec
Гость
« Ответ #3 : Октябрь 21, 2015, 23:08 »

По идее вам нужно не читать файл десятью потоками, а читать одним и передавать десятью Улыбающийся

PS это не то, что вы просите, но это примерно на 80% даст тот же результат.

PPS ну или можно сильно заморочиться, ввести хранилище хендлов на файлы или использовать неблокирующее чтение или кеширование. Но тут уже надо исходя из задачи выбирать.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.122 секунд. Запросов: 22.